2016-12-22 8 views
1

У меня есть таблица с двумя значениями: MAC и ID.T-SQL Найти значения между Min и Max при определенном индексе

Один идентификатор может иметь несколько MAC-адресов. Для примера:

enter image description here

Я добавил столбец Count, который подсчитывает количество идентификаторов:

enter image description here

Моя конечная цель, чтобы иметь MAC разделимся так:

enter image description here

Я ДУМАЮ, Я нахожусь на правильном пути, используя аргументы case:

select count, ID, 
MAC1 = case 
when count >0 then min(MAC) end, 
MAC2 = case 
when count = 2 then max(MAC) end, 
MAC3 = case 
when count = 3 then max(MAC) end, 
MAC4 = case 
when count = 4 then max(MAC) end from MACTABLE 

Но это, очевидно, дает мне результаты, как это:

enter image description here

Так что мой вопрос заключается в следующем: Как получить mac2, MAC3 и т.д., если количество больше чем 2? Есть ли выбранная функция типа индекса? Могу ли я это переусердствовать? MAC не обязательно должны быть в определенном порядке, это лучший способ, которым я мог бы это сделать. Любая помощь приветствуется.

+1

Я хотел бы получить максимальное количество и исходя от этого числа создать столбцы с шарниром. – scsimon

+0

@scsimon, я слышал о pivot, но никогда не использовал его раньше. Не могли бы вы объяснить немного дальше? – Nick

+1

Есть много примеров на сводной и динамической основе на SO, но вот пример того, как получить имена столбцов, чтобы начать работу http://rextester.com/NJOQ46585 – scsimon

ответ

1
CREATE TABLE [MAC$] (
    [ID] int, 
    [MAC] varchar(10) 
) 
INSERT [dbo].[MAC$] ([ID], [MAC]) VALUES (1, N'120034') 
INSERT [dbo].[MAC$] ([ID], [MAC]) VALUES (1, N'567869') 
INSERT [dbo].[MAC$] ([ID], [MAC]) VALUES (1, N'741AB00') 
INSERT [dbo].[MAC$] ([ID], [MAC]) VALUES (2, N'185AZ1') 
INSERT [dbo].[MAC$] ([ID], [MAC]) VALUES (2, N'FD8978') 
INSERT [dbo].[MAC$] ([ID], [MAC]) VALUES (3, N'H85HLK') 
GO 
SELECT * FROM 
(SELECT Id, CAST([Mac] as varchar(10)) as val, 'MAC_' + CAST(DENSE_RANK() OVER (PARTITION BY Id ORDER BY Id, Mac) as varchar(10)) as namePivot FROM [Mac$] WHERE LEN(Mac)>0) as data 
PIVOT (MAX(val) FOR namePivot in ([MAC_1],[MAC_2],[MAC_3],[MAC_4],[MAC_5])) as P 
GROUP BY Id,[MAC_1],[MAC_2],[MAC_3],[MAC_4],[MAC_5] 

Рекомендуемый способ для расширения его на MAC_N:

DECLARE @sColMac varchar(MAX); 
DECLARE @iNumMac int; 
SET @iNumMac = 1; 
WHILE @iNumMac <= 5 
    BEGIN 
    SELECT @sColMac = COALESCE(@sColMac + ',', '') + QUOTENAME('MAC_' + CONVERT(varchar(10),@iNumMac)) 
    SET @iNumMac = @iNumMac + 1 
    END 

SELECT @sColMac 
+0

Можете ли вы масштабировать его для N числа MAC? – scsimon

+0

Для этого потребуется динамический sql. Я нашел, что лучше не идти по этому маршруту, потому что очень сложно отлаживать (поскольку все должно быть записано как строка). Вы можете сделать что-то вроде добавления в моем отредактированном ответе и просто вручную заменить две строки [MAC_N]. –

+0

@mikemorris Это сработало отлично! У меня есть один вопрос. Если бы я хотел его масштабировать, скажем, что у ID может быть 4 MAC и 4 SN, и я хотел бы иметь MAC_1, MAC_2 и т. Д. SN_1, SN_2, можно ли обрабатывать опорную функцию, или она должна быть двух отдельных? В любом случае, это именно то, что мне нужно, большое вам спасибо! – Nick

0
SELECT * 
FROM 

    (
    select case when x.COUNTID = 1 then 'MAC1' when x.COUNTID = 2 then 'MAC2' when x.COUNTID = 3 then 'MAC3' when x.COUNTID = 4 then 'MAC4' end MAC 
      ,ID 
      ,COUNTID 
    from 
     (-- YOUR ORIGINAL (COUNT) QUERY----- 
      select mac 
        ,ID 
        ,count(ID) COUNTID 
      from YOUR_TABLE 
      group by mac, ID 
     ) x 
    ) SRC 
pivot(
    sum(COUNTID) 
    for mac in ([MAC1], [MAC2], [MAC3], [MAC4])) piv 
Смежные вопросы