SQL GROUP BY с агрегатом - PullRequest
       6

SQL GROUP BY с агрегатом

2 голосов
/ 15 февраля 2012

Если у меня есть таблица чисел с данными:

+------+------+------+------+
| colA | colB | colC | colD |
+------+------+------+------+
|    1 |    2 |    3 |    4 |
|    1 |    2 |    9 |    5 |
+------+------+------+------+

и я делаю:

select colA, colB, colC, MAX(colD) FROM Numbers GROUP BY colA, colB;

Я считаю, что она должна вернуть строку 2. Она группируется по colA, colB и выбираетсамый большой в colD.

К сожалению, это не работает, потому что вам также нужно сгруппировать по colC, чтобы вернуть его.

Почему?Есть ли другой способ сделать то, что я пытаюсь сделать?

Я хочу строку с таким же в colA и colB, но самый большой в colD.

Ответы [ 3 ]

5 голосов
/ 15 февраля 2012

Есть несколько способов справиться с этим. Возможно, самым простым является JOIN для подзапроса, который делает группу colA, colB и находит из нее полную соответствующую строку.

SELECT 
  tbl.colA,
  tbl.colB,
  tbl.colC,
  tbl.colD
FROM tbl JOIN (
  SELECT
    colA,
    colB,
    MAX(colD) AS maxD
  FROM tbl
  GROUP BY colA, colB
) g ON tbl.colA = g.colA AND tbl.colB = g.colB AND tbl.colD = g.maxD
3 голосов
/ 15 февраля 2012

Вы можете сделать это:

 SELECT N1.colA, N1.colB, N1.colC, N1.colD
   FROM Numbers N1
   LEFT JOIN Numbers N2 ON N2.colA = N1.colA
                       AND N2.colB = N1.colB
                       AND N2.colD > N1.colD
  WHERE N2.colA IS NULL;

LEFT JOIN будет искать строку в той же таблице с теми же столбцами A и B и большим столбцом D. Если строка не найдена, у вас есть максимальное значение в столбце D.

Технически это так же, как:

SELECT *
  FROM Numbers N
 WHERE NOT EXISTS
     ( SELECT NULL /* or whatever you want, doesn't matter */
         FROM Numbers
        WHERE colA = N.colA
          AND colB = N.colB
          AND colD > N.colD
     )

Обратите внимание, что вы можете добавить DISTINCT, если это возвращает двойные строки.

0 голосов
/ 15 февраля 2012

Одной из проблем вашего запроса является то, что вы хотите показать значение codC, но оно не входит в группу по частям. Чтобы показать значение без функции агрегирования, оно должно быть в группе по частям. Поэтому, чтобы исправить ваш запрос, вы можете сделать что-то вроде этого:

select n1.* from Number n1
inner join (select colA, colB, max(colD) as colD from Number GROUP BY colA, colB) n2 on n1.colA = n2.colA and n1.colB = n2.colB and n1.colD = n2.colD

Он выберет все строки с максимальным (colD) для каждого colA и colB.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...