Присоединение к трем столам, затем группа

Я собираюсь объединить три таблицы, а затем суммировать один из столбцов, умноженный на значение из другого.

SELECT t1.column, t2.column, SUM(t1.column * t2.column)
FROM table1 t1 
     INNER JOIN table2 t2 
         ON t1.id = t2.id 
     JOIN table3 t3 
         ON t2.id = t3.id 
GROUP BY t1.column, t2.column;

Этот запрос делает то, что я хочу, НО я не понимаю, почему работает GROUP BY?

Если я добавляю столбцы в выбор, должен ли я также добавлять столбцы в группу?


person LuckyLuke    schedule 16.02.2011    source источник
comment
что-нибудь для чтения w3schools.com/sql/sql_groupby.asp   -  person Kris Ivanov    schedule 16.02.2011
comment
Это ограничение GroupBy. Все столбцы неагрегации должны быть частью пункта Group By... Однако ваш вопрос мне не ясен... Что именно вы спрашиваете?   -  person S M Kamran    schedule 16.02.2011
comment
Все неагрегированные столбцы должны быть частью предложения Group By... @S M Kamran: по крайней мере, это неверно для MySQL.   -  person ypercubeᵀᴹ    schedule 16.02.2011


Ответы (6)


Ты вообще знаешь, что ты здесь делаешь?

SELECT t1.column, t2.column, SUM(t1.column * t2.column)
FROM table1 t1
INNER JOIN table2 t2 ON t1.id = t2.id
JOIN table3 t3 ON t2.id = t3.id
GROUP BY t1.column, t2.column;

Запрос очень подозрительный по крайней мере в двух отношениях:

  • Таблица3 не используется, за исключением проверки существования записи в t3 для идентификатора в t2. Ты этого хотел? Potential pitfall Если на запись t2 приходится несколько записей T3, вы получите декартово произведение, непреднамеренное умножение столбца СУММ.

  • GROUP BY t1.column, t2.column – объединяет все уникальные комбинации (t1.column, t2.column) и суммирует по ним результат t1.column * t2.column. Это действительно то, что вам нужно?

Для пункта 2 рассмотрим эти (исходные) данные:

t1.id, t1.column, t2.column, t1.column*t2.column
1      2          3          6
2      2          3          6
3      3          3          9
4      3          4          12

Вы в конечном итоге с выходом

t1.column, t2.column, SUM(t1.column*t2.column)
2          3          12
3          3          9
3          4          12

Видите, что (2,3) объединило сумму.

Если я добавляю столбцы в выбор, я также должен добавить столбцы в группу.

Столбцы в SELECT (за исключением некоторых СУБД, таких как MySQL) должны быть либо агрегатом (например, sum/avg/min/max), либо столбцом в предложении GROUP BY. Есть и другие выражения, например скалярные функции или константы, которые можно использовать не напрямую из таблиц.

Если вам действительно нужно больше столбцов из таблицы, связанных с агрегированными данными, вам нужно четко обдумать почему. например Если вы группируете по столбцу1 и усредняете столбец2, что вы пытаетесь сделать с столбцом3 - из какой строки он должен исходить?

person RichardTheKiwi    schedule 16.02.2011

Это связано с тем, что SUM — это функция агрегирования, которая рассчитывается на основе результата каждой группы.

person Albin Sunnanbo    schedule 16.02.2011

Сначала не беспокойтесь о JOIN. Чтобы понять GROUP BY, сначала рассмотрим очень простой запрос.

SELECT t1.year, t1.person
FROM table t1

Это вернет

year | person
2000 | Joe
2000 | Betty
2000 | Marty
2001 | Joe
2002 | Betty

Если вы добавляете агрегатную функцию, вы должны включить GROUP BY для всего, что не охвачено агрегатной функцией.

SELECT t1.year, COUNT(t1.person) as counter
FROM table t1
GROUP BY t1.year
year | counter
2000 | 3
2001 | 1
2002 | 1

Если вы не включите GROUP BY, это не сработает, потому что база данных буквально не знает, как вы хотите сгруппировать свои данные.

person Nathan DeWitt    schedule 16.02.2011

Когда GROUP BY имеет более 1 параметра, как в вашем случае, это означает «Сначала сортировать по определению № 1, и если есть несколько определений № 1, затем сортировать по определению № 2, если есть несколько определений № 2, затем сгруппировать их вместе.".

person servermanfail    schedule 16.02.2011

Столбцы, являющиеся целью агрегатных функций, не обязательно должны быть частью предложения GROUP BY. Агрегатные функции — это такие функции, как SUM, AVG, MIN, MAX и т. д.

person Tommi    schedule 16.02.2011

Поскольку агрегатные функции дают вам одно возвращаемое значение...

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

person S M Kamran    schedule 16.02.2011