Как использовать group by для получения нескольких наборов результатов? группировка по нескольким столбцам

#php #mysql #sql #database #group-by

#php #mysql #sql #База данных #group-by

Вопрос:

У меня есть таблица с именем product, которая содержит следующие данные

pid фирменный цвет 

1 sony white
2 casio серый
3 xoxo blue
samsung 4 white
5 mvc silver
6 sony gray
7 xoxo red 
8 samsung silver
9 mvc white

Мне нужно получить общее количество товаров, принадлежащих каждому бренду и цвету. Итак, я написал 2 разных запроса.

Выберите count (pid) как total из группы продуктов по бренду;
Выберите количество (pid) как общее из группы продуктов по цвету;

Это работает нормально. Но поскольку данные моей таблицы продуктов огромны, я думаю, будет лучше, если я смогу достичь этого с помощью одного запроса. Возможно ли это?

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

1. Вопрос несколько запутанный. Когда вы говорите «получить общее количество товаров, относящихся к каждому бренду и цвету», вы имеете в виду получить количество отдельно или сначала сгруппировать бренд, а затем сгруппировать по цвету, а затем получить количество?

2. Хорошо, я внесу ясность. Мне нужно подсчитывать отдельно. т.е. общее количество продуктов относится к каждому бренду, а общее количество продуктов относится к каждому цвету. Не сочетание бренда и цвета.

Ответ №1:

Вы могли бы просто использовать UNION эти два запроса:

 ( SELECT 1        AS groupType
       , brand    AS grp
       , count(*) AS total
  FROM products 
  GROUP BY brand
)
UNION ALL
( SELECT 2        AS groupType
       , color    AS grp
       , count(*) AS total
  FROM products 
  GROUP BY color
)
ORDER BY groupType
       , grp
  

Если вам нужно количество товаров для каждой комбинации бренда и цвета, у вас должна быть таблица, сгруппированная по этим двум полям:

 SELECT brand
     , color
     , count(*) AS total
FROM products 
GROUP BY brand
       , color
  

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

1. Привет. Спасибо за ваш ответ. Здесь у меня есть сомнения. В чем преимущество использования union по сравнению с использованием 2 отдельных запросов? Приведет ли это к повышению производительности? На самом деле бренд и цвет, которые я упомянул в этом примере, являются атрибутами продукта. В моей фактической таблице всего 6 атрибутов. Итак, какой подход будет лучше? Запрос объединения всех 6 запросов или 6 отдельных запросов?

Ответ №2:

В зависимости от того, насколько велика ваша таблица на самом деле, может быть дешевле сначала получить итоговые данные для комбинаций бренда / цвета и сохранить их во временной таблице, а затем дважды запросить временную таблицу, чтобы найти окончательные итоги по каждому критерию.

То есть, что-то вроде этого:

 -- create a temporary table (omitted)

INSERT INTO temp_table (brand, color, total)
SELECT brand, color, COUNT(*) AS total
FROM products
GROUP BY brand, color

SELECT brand, SUM(total) AS total
FROM temp_table
GROUP BY brand

SELECT color, SUM(total) AS total
FROM temp_table
GROUP BY color
  

Ответ №3:

 select 
count(*) over (partition by product), 
count(*) over (partition by color)
from table
  

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

1. Я не думаю, что у MySQL есть раздел.

2. @PMV: вы правы, это одна из немногих СУБД, которая не поддерживает оконные функции

Ответ №4:

 select brand as `group`, count(pid) from products group by brand
union all
select color as `group`, count(pid) from products group by color
  

Ответ №5:

Группировка по отдельности по двум разным столбцам приводит к двум принципиально разным запросам, поэтому с точки зрения базы данных их проще запускать по отдельности. Я бы подумал о создании двух индексов (один по бренду, другой по цвету), чтобы помочь.

Ответ №6:

Это возможно с помощью операторов with , но это недоступно в MySQL на момент написания этого ответа.

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

1. Это все равно не дало бы вам полезного набора результатов. Вы получите столько же строк, сколько и в исходной таблице, в которых случайно есть количество для марки и цвета этой строки. Затем вам придется добавить group by, и у вас, вероятно, будет еще более дорогостоящий запрос, чем просто выполнение выборок по отдельности.

2. На самом деле нет: оператор over() делает это эквивалентным написанию двух запросов по отдельности. Но опять же, недоступно в MySQL.

3. Хотя значения будут правильными, у вас все равно будет строка для каждого возвращаемого продукта.

Ответ №7:

 $sql = "SELECT col_1, SUM(col_2), SUM(col_3) FROM table_name GROUP BY(col_1)";
  

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

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