2017-02-08 2 views
1

У меня есть таблица SQL с тремя полями Id, Player, ColorNumber. Идентификатор не является первичным ключом и может быть повторен. Вот таблица выглядит следующим образом:MS sql хранимые процедуры агрегированные данные на основе некоторых условий

enter image description here

Я хочу использовать это, чтобы создать таблицу капитаны, например. Но капитан должен быть выбран в максимальных случаях игрока для данного Идентификатора.

например. Для 123 Майк встречается чаще всего, капитан должен быть Майком. Для 345, нет ясного большинства, поэтому оставить поле капитана пустым Для 567 это будет Schuyler, хотя пространство и Schuyler имеют одинаковые подсчеты. Для 898 это Мария. Обратите внимание, что Майк также встречается в ключе 898.

Вот мой вывод.

enter image description here

До сих пор я писал:

SELECT COUNT(*) as counts,[Class ID],Player 
    FROM [Test].[dbo].[Players] 
    GROUP BY [Class ID],Player 

, который дал мне результат, как:

enter image description here

Я предполагаю, что хранимая процедура будет лучшим способом напишите это и получите новую таблицу против нового прямого запроса. Так как мне нужно обработать случай, если в случае одинаково встречающихся имен капитан будет пустым. Тем не менее, я довольно новичок в хранимых процедурах и не знаю, как это сделать, и повторно использую информацию из запроса выше, чтобы сделать это и обработать дела. Я думаю, что есть CASE .. КОГДА операция я смотрел в процедурах, но я не уверен, как я могу это использовать.

Просьба предложить, если у вас есть другая альтернатива, а не процедура. Любая помощь будет оценена по достоинству.

ответ

1

Это называется «режим» в статистике. Вы можете легко сделать это с помощью функции окна:

SELECT [Class ID], 
     COALESCE(MAX(CASE WHEN seqnum = 1 THEN PLAYER END), MAX(CASE WHEN seqnum = 2 THEN PLAYER END) 
       ) as captain 
FROM (SELECT COUNT(*) as counts, [Class ID], Player, 
      ROW_NUMBER() OVER (PARTITION BY [Class ID] ORDER BY COUNT(*) DESC) as seqnum 
     FROM [Test].[dbo].[Players] p 
     GROUP BY [Class ID], Player 
    ) p 
GROUP BY [Class ID]; 

Примечания: COALESCE() необходима, потому что у вас есть много пустых значений. Я подозреваю, что вы не хотите их для капитана.

EDIT:

Если вы не хотите ни когда есть связи:

SELECT [Class ID], 
     (CASE WHEN MAX(CASE WHEN seqnum = 1 AND cnt = 1 AND player IS NOT NULL THEN 1 ELSE 0 END) = 1 
      THEN PLAYER 
      WHEN MAX(CASE WHEN seqnum = 1 AND cnt > 1 THEN 1 ELSE 0 END) > 0 
      THEN NULL 
      WHEN MAX(CASE WHEN seqnum = 2 AND cnt = 1 
      THEN PLAYER 
      END) as captain 
FROM (SELECT p.*, COUNT(*) OVER (PARTITION BY [Class ID], seqnum) as cnt 
     FROM (SELECT COUNT(*) as counts, [Class ID], Player, 
        DENSE_RANK() OVER (PARTITION BY [Class ID] ORDER BY COUNT(*) DESC) as seqnum 
      FROM [Test].[dbo].[Players] p 
      GROUP BY [Class ID], Player 
      ) p 
    ) p 
GROUP BY [Class ID]; 
+0

Привет Гордон, это потрясающий ответ. Спасибо. –

+0

Но выход я получаю 123-> Mike, 345-> Randy, 567->, 898-> Mary 123 и 898 верны. На 345 у всех игроков одинаковое количество очков, поэтому я хочу оставить капитана пустым. Для 567 Шайлер имеет 2, пространство имеет 2. Оба равны, но я хочу, чтобы Шайлер был капитаном. Как вы можете видеть мой результат. Это похоже на про-уровень SQL! Брилиант, но все-таки ушел. –

+0

SELECT [Идентификатор класса], COALESCE (MAX (CASE WHEN seqnum = 1 и PLAYER не в состоянии ('', '') ТОЛЬКО ИГРАТЬ КОНЕЦ), MAX (CASE WHEN seqnum = 2 THEN PLAYER END) ) в качестве капитана FROM (SELECT COUNT (*) в качестве счетчиков, [Class ID], Player, ROW_NUMBER() OVER (PARTITION by [ID класса] ORDER BY COUNT (*) DESC) как seqnum FROM [Test]. [Dbo].[Игроки] p ГРУППА BY [Идентификатор класса], Игрок ) p ГРУППА BY [Идентификатор класса]; Это заставляет меня так далеко, за исключением ввода пустого, если нет четких максимальных значений. @Gordon Linoff –