2015-08-02 4 views
3

У меня есть следующий Postgres SQL-запрос:SQL GROUP_BY дополнительный столбец

SELECT movement_id, counter, MAX(standardized_output) AS standardized_output 
FROM "outputs" 
WHERE "outputs"."user_id" = 1 AND "outputs"."movement_id" = 1 AND (counter in (1,3,5)) 
GROUP BY movement_id, counter 

Это хорошо производит три ряда для меня.

Однако я также хочу потянуть в соответствующую колонку done_at. Добавление done_at в SELECT и GROUP_BY заканчивается тем, что возвращает сотни строк; Я просто хочу, чтобы три строки возвращали вышеуказанный запрос с соответствующим полем done_at для выходной строки, которая была найдена функцией MAX.

ответ

0

Если вы хотите поле done_at со значением max вам не нужно, чтобы добавить его в пункте group by вы должны добавить его с максимальной функции как ниже

SELECT movement_id, 
     counter, 
     MAX(standardized_output) AS standardized_output, 
     MAX(done_at) 
    FROM "outputs" 
WHERE "outputs"."user_id" = 1 
    AND "outputs"."movement_id" = 1 
    AND counter in (1,3,5) 
GROUP BY movement_id, counter 

Вы можете использовать несколько агрегатных столбцов на том же sql. Я думаю, что done_at является столбцом даты, и из-за этого вы получаете сотни строк.

+0

Это не обязательно возвращает значение '' done_at' где standardized_output' находится на максимальном значении , – Patrick

+1

@ Patrick, похоже, работает правильно для меня? –

+0

@BenSmith Для каждой комбинации '(movement_id, counter)' вы получите максимальное значение 'standardized_output' и' done_at'. Если эти максимальные значения происходят из одной и той же строки, то это сработает, но что, если 'done_at' - какое-то низкое значение, где' standardized_output' максимален? Таким образом, это может работать для некоторых, возможно, даже для большинства или всех ваших данных, но также может возвращать значения для 'standardized_output' и' done_at' в комбинации, которая не предоставляется одной строкой. – Patrick

1

Используйте КТР с ROW_NUMBER

WITH CTE AS 
(SELECT movement_id, counter, standardized_output ,done_at, 
ROW_NUMBER() OVER (PARTITION BY movement_id, counter ORDER BY standardized_output DESC) as RN 
FROM "outputs" 
WHERE "outputs"."user_id" = 1 AND "outputs"."movement_id" = 1 AND (counter in (1,3,5)) 
) 
SELECT * FROM CTE WHERE RN=1 
0

Рассмотрим с помощью производной суб запроса таблицы:

SELECT t2.movement_id, t2.counter, t2.standardized_output, t1.done_at 
FROM "outputs" t1 
INNER JOIN 
    (SELECT movement_id, counter, MAX(standardized_output) AS standardized_output 
     FROM "outputs" 
    WHERE "outputs"."user_id" = 1 AND "outputs"."movement_id" = 1 
     AND (counter in (1,3,5)) 
    GROUP BY movement_id, counter) t2 
ON t1.movement_id = t2.movement_id 
Смежные вопросы