У меня есть таблица project_product
и таблица project_consummation
. Люди потребляют продукт, и может дать продукту оценку от 1 до 10.Подведение итогов оценки для многих продуктов
Позвольте мне ASCII искусство для осветления:
+--------------------------+ +-------------------------+
| project_product | | project_consummation |
|--------------------------| |-------------------------|
| id integer primary key |-\ | id integer primary key |
| name varchar | \->| product_id integer |
| ... | | rating integer |
| various other fields... | | user_id integer |
+--------------------------+ | ... |
| various other fields... |
+-------------------------+
Теперь я хочу обзор голосов для продукта. Конечно, может быть consummation
s без значения rating
(например, NULL), поэтому их необходимо игнорировать.
Результат должен выглядеть следующим образом (каждый рейтинг от 1 до 10 должен иметь свой столбец, указывающий количество людей, которые дали продукт этот рейтинг, а также общее количество рейтингов num_ratings
и, возможно, позже некоторые медианные, стандартные отклонение и т.д.):
product_id | rating1 | rating2 | ... |rating10 | num_ratings
------------+---------+---------+-----+---------+-------------
1002 | | | ... | 1 | 1
1014 | 4 | | ... | 2 | 6
1015 | 2 | 1 | ... | 1 | 4
Я создал «решение», которое является довольно неуклюжим, потому что я делаю LEFT OUTER JOIN
для каждого рейтинга колонки, как это (я только показать первые 3 колонки, но я уверен, вы увидите, какой беспорядок это станет):
SELECT p.id AS product_id,
rating1, rating2, rating3,
COALESCE(rating1, 0) + COALESCE(rating2, 0) + COALESCE(rating3, 0) AS num_ratings
FROM project_product p
LEFT OUTER JOIN
(SELECT product_id,
count(*) AS rating1
FROM project_consummation c
WHERE rating = 1
GROUP BY product_id
) c1 ON p.id = c1.product_id
LEFT OUTER JOIN
(SELECT product_id,
count(*) AS rating2
FROM project_consummation c
WHERE rating = 2
GROUP BY product_id
) c2 ON p.id = c2.product_id
LEFT OUTER JOIN
(SELECT product_id,
count(*) AS rating3
FROM project_consummation c
WHERE rating = 3
GROUP BY product_id
) c3 ON p.id = c3.product_id
Что было бы лучшим решением в отношении лучшего кода и особенно лучшей производительности?
Есть еще 2 способа сделать это, Используя перекрестную функцию, которая будет величина быстрее, чем ваш «неуклюжий» ПОДХОД и другое мое предложение приемлемо, используя операторы случае как «сумма (случай, когда рейтинг = 1, то 1 else 0 end) как рейтинг1, сумма (случай, когда рейтинг = 2, а затем еще 1 конец 0) как рейтинг2 .... " –
Это выглядит как интересный ответ. Не могли бы вы создать реальный ответ из своего комментария? – mawimawi
Я могу, через полчаса .... бит занят –