Запрос к кростабу Mysql

#mysql #crosstab

#mysql #перекрестная таблица

Вопрос:

Существует несколько таблиц для хранения содержимого и категорий. Содержимое и категории отображаются в отношениях «многие ко многим».

Категория может содержать много содержимого.

Контент может быть включен во многие категории.

Поэтому я создал таблицу content_cat_xref для сопоставления этих таблиц.

таблица категорий — идентификатор, имя и т. Д

таблица содержимого — идентификатор, имя, type_code (read_it, play_it, prove_it, watch_it)

content_cat_xref — content_id, category_id и т. Д

Я хотел отобразить категории с типами контента и количеством содержимого для каждого типа контента следующим образом.

введите описание изображения здесь

Но я получаю следующее.

введите описание изображения здесь

Мой запрос заключается в следующем

 select 
ccx.category_id, 
IF(count(c.id) > 0, "True", "False") as Sections_with_content,
(CASE WHEN (c.type_code = 'READ_IT') THEN count(c.id) ELSE 0 END) as "READ_IT",
(CASE WHEN (c.type_code = 'WATCH_IT') THEN count(c.id) ELSE 0 END) as "WATCH_IT",
(CASE WHEN (c.type_code = 'PLAY_IT') THEN count(c.id) ELSE 0 END) as "PLAY_IT",
(CASE WHEN (c.type_code = 'PROVE_IT') THEN count(c.id) ELSE 0 END) as "PROVE_IT",
count(c.id) 
  from content_cat_xref as ccx left outer join content as c
  on ccx.content_id = c.id 
  group by ccx.category_id, c.type_code
  

Если у кого-то есть подобный опыт, мне будет полезно решить проблему.

Ответ №1:

Не группируйте по c.type_code , потому что это приводит к тому, что различные типы группируются в отдельные записи. Весь смысл условных подсчетов заключается в том, чтобы работать со всей общей группой (в данном случае category_id ) и возвращать только соответствующие подсчеты.

Обновить

Вам также необходимо изменить способ выполнения условных подсчетов. Условие должно быть внутри функции count() (или sum()), а не вне ее, поскольку вы хотите, чтобы результаты отображались во всех случаях. Итак, вместо

 (CASE WHEN (c.type_code = 'READ_IT') THEN count(c.id) ELSE 0 END) as "READ_IT"
  

есть

 COUNT(CASE WHEN (c.type_code = 'READ_IT') THEN 1 ELSE NULL END) as "READ_IT"
  

Объяснение: case Инструкция возвращает значение 1 , если условие выполнено, и возвращает null , если это не так. Count() функция подсчитывает все ненулевые значения. Измените выражение всех других полей на основе приведенного выше примера.

Комментарии:

1. Спасибо за комментарий. Затем он покажет общее количество в коде неправильного типа. Не могли бы вы, пожалуйста, помочь мне получить соответствующее количество в этом случае?

2. Извините, но я не понимаю вашего последующего вопроса.

3. Хм, думаю, я понял, я обновлю свой ответ через минуту.

4. Большое спасибо. Это работает нормально. Один вопрос. Почему мы используем NULL вместо 0 здесь. ТОГДА 1 ЕЩЕ НУЛЕВОЙ КОНЕЦ

5. Я объяснил это в последнем абзаце ответа.