Запрос SQL Server выберите 1 из каждой подгруппы - PullRequest
5 голосов
/ 07 июня 2011

У меня есть набор данных, и мне нужно извлечь одну запись для каждого набора CON / OWNER / METHOD / MATRIX. Если есть ненулевой РЕЗУЛЬТАТ, я хочу этот. В противном случае, я хочу тот, с самым высоким COUNT. Как я могу запросить это?

CON      OWNER      METHOD      MATRIX  RESULT  COUNT
*CON_1   OWNER_1    METHOD_A    SOLID   NULL    503
CON_1    OWNER_1    METHOD_A    SOLID   NULL    1

*CON_1   OWNER_1    METHOD_A    SOIL    NULL    1305
CON_1    OWNER_1    METHOD_A    SOIL    NULL    699

*CON_2   OWNER_2    METHOD_B    SOLID   290     687
CON_2    OWNER_2    METHOD_B    SOLID   NULL    NULL
CON_2    OWNER_2    METHOD_B    SOLID   450     600

CON_2    OWNER_2    METHOD_B    WATER   NULL    1
*CON_2   OWNER_2    METHOD_B    WATER   400     NULL

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

Это плохой SQL:

select top (1) CON, OWNER, METHOD, MATRIX, RESULT, COUNT
from #TempTable
group by CON, OWNER, METHOD, MATRIX
order by CON, OWNER, METHOD, MATRIX, COUNT

... потому что мой счет не является частью агрегатной функции. Он также не касается того, что RESULT равен NULL или нет, и top (1) не вернет 1 из каждой группы. Тем не менее, я не пошел дальше, используя более сложный запрос (например, основанный на вопросе на Как выбрать несколько столбцов из подзапроса (в SQL Server), который должен иметь одну запись (выберите top 1) для каждая запись в основном запросе? )

Как выбрать один из каждой группы?

Ответы [ 3 ]

11 голосов
/ 07 июня 2011

Попробуйте, не на 100% уверены, что синтаксис правильный, но он близок.

select 
    * 
from
    (select
        CON,
        OWNER,
        METHOD,
        MATRIX,
        RESULT,
        COUNT,
        RANK() OVER(PARTITION BY CON, OWNER, METHOD,MATRIX ORDER BY RESULT,COUNT DESC) as rnk
    FROM #TempTable
) a
WHERE rnk = 1
2 голосов
/ 07 июня 2011

В СУБД, которая поддерживает управление окнами (включая SQL Server 2008, я полагаю)

SELECT CON, OWNER, METHOD, MATRIX, RESULT, `COUNT`
FROM
 (SELECT CON, OWNER, METHOD, MATRIX, RESULT, `COUNT`, 
  RANK() OVER (PARTITION BY CON, OWNER, METHOD, MATRIX
               ORDER BY RESULT DESC, `COUNT` DESC) AS rk
  FROM temptable
 ) AS s
WHERE rk=1;

Обратите внимание, что ваш текст подразумевает только один ненулевой результат на группу, а ваш пример - нет.Эта версия выберет максимальный результат, если все результаты не будут одинаковыми (например, NULL), когда count будет тай-брейком.Кстати, COUNT как имя столбца будет вызывать всевозможные печали.Эта версия также выбирает несколько строк в случае связей как в результате, так и в счетчике.Переключите ранг на row_number, чтобы получить только один, независимо от того, есть ли связь.

0 голосов
/ 14 декабря 2012
select DetailID, field2, field3, field4, MasterID 
from table outer
where DetailID= 
    (
        select max(DetailID) 
        From table inner 
        where outer.MasterID = inner.MasterID
        group by MasterID 
    )

Вы можете использовать его как вид и присоединиться.

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