2015-12-14 2 views
2

У меня есть таблица PostgreSQL, которая выглядит как:SQL: несколько вложенных агрегатных функций

artists | songs 
=================== 
artist1 | song a 
artist1 | song b 
artist2 | song c 

и я хочу сделать отборное заявление, которое дает мне для каждого художника количество дорожек, а разница между числом его следы и количество художника с наиболее треки

так в этом случае

artist | number songs | difference 
==================================== 
artist1 | 2   | 0 
artist2 | 1   | 1 

проблема у меня в том, что я использую count(songs) для го e количество песен, а также max(count(songs)) (необходимое для вычисления разницы) в том же самом результате. И использование обоих дает мне проблемы с вложенными агрегированными функциями.

ответ

2

Вы можете использовать комбинацию агрегатных функций (подсчитать количество песен на художник) и функцию окна, чтобы произвести этот результат:

SELECT artist, 
     COUNT(*) AS num_songs, 
     MAX(COUNT(*)) OVER (ORDER BY COUNT(*) DESC) - COUNT(*) AS diff 
FROM  artists              
GROUP BY artist; 

Это немного неуклюжее, но лань трюка.

РЕДАКТИРОВАТЬ:
Как прокомментировал @a_horse_with_no_name, положение в предложении overorder by является излишним. Удаление этого кода упрощает чтение кода:

SELECT artist, 
     COUNT(*) AS num_songs, 
     MAX(COUNT(*)) OVER() - COUNT(*) AS diff 
FROM  artists              
GROUP BY artist; 
+0

'order by' в разделе' over() 'на самом деле не требуется. –

+0

@a_horse_with_no_name huh! никогда не знал, что наличие пустого предложения 'over' было даже возможно, но я играл с ним немного после вашего комментария, и он определенно работает (и выглядит намного, намного чище). Узнал что-то сегодня, спасибо! (отредактированный в моем ответе тоже) – Mureinik

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