2014-01-07 2 views
0

Я хотел бы решить проблему с ситуацией, аналогичной следующими данными,SQL группы колонки еще игнорировать дублированный элемент другого столбца

company customer pay sequence 
a  x  5 1 
a  x  6 2 
b  x  3 3 
b  y  4 4 
a  y  2 5 

И я хочу, чтобы получить результат, вычисляя суммирование группы «платить» компании, но дублированный клиент будет использовать только один раз, основываясь на последней последовательности. Таким образом, ожидаемый результат

company sum(pay) 
a  8 
b  7 

Это означает, что компания «а» сумма (оплата) 8 поступает из второго ряда и с последней строкой. И компания «b» сумма (оплата) 7 поступает из 3-го и 4-го рядов. И первая строка игнорируется.

Таким образом, я использую такой запрос (PostgreSQL), чтобы решить эту проблему,

select t2.company,sum(t2.pay) from mytable t2 join (
    select company,customer,max(sequence) as sequence 
    from mytable group by company,customer 
) t1 on t1.sequence=t2.sequence group by t2.company 

Я хотел бы знать, есть ли там какой-нибудь простой способ использовать запрос без подзапроса, как указано выше?

+2

Что такое "не просто" о запросе? Мне кажется очень разумным. –

ответ

2

В Postgres, вы можете сделать это без join, используя синтаксис distinct on:

select t.company, sum(t.pay) 
from (select distinct on (company, customer) company, customer, pay 
     from mytable 
     order by company, customer, sequence desc 
    ) t 
group by t.company; 

Я предпочитаю метод в ОП, так как он является стандартом SQL. Заявление distinct on находится только в Postgres.

+0

+1, хороший, не знал об этом в Postgres – Lamak

0

Другой способ сделать это было бы использовать ROW_NUMBER, но я не знаю, если вы можете сказать, что это «легче» путь:

WITH CTE AS 
(
    SELECT *, 
     ROW_NUMBER() OVER(PARTITION BY company, customer 
          ORDER BY sequence DESC) AS RN 
    FROM YourTable 
) 
SELECT company, 
     SUM(pay) AS pay 
FROM CTE 
WHERE RN = 1 
GROUP BY company 
ORDER BY company 

Результаты:

╔═════════╦═════╗ 
║ COMPANY ║ PAY ║ 
╠═════════╬═════╣ 
║ b  ║ 7 ║ 
║ a  ║ 8 ║ 
╚═════════╩═════╝ 

And here is sqlfiddle с демо для вас, чтобы попробовать.

0

Использование функции windows - это еще один вариант,
Я не уверен, что это более простой или быстрый способ.
В моем примере это невозможно сделать без подзапроса.

SELECT company,sum(pay) 
FROM (
    SELECT *, 
      max(sequence) OVER (partition by company,customer) max_seq 
    FROM table1 
) AS t 
WHERE sequence = max_seq 
GROUP BY company 

Демо: http://www.sqlfiddle.com/#!15/f66b3/4

Смежные вопросы