2015-06-22 3 views
0

Вот моя текущая ситуация:Microsoft SQL Server: Добавление нового столбца строка вместо повторных значений

Я представил длинный список данных, содержащие имена и значение, с соответствующим значением ID. Количество идентификаторов может варьироваться для представленных данных, но является постоянным для всего набора. (Этот набор будет иметь ровно 2 значения для имени). Дело в том, что имена повторяются, но идентификаторы этого не делают. Мой вопрос становится,

Как я могу преобразовать таблицу, которая выглядит следующим образом:

Name | ID | Value 
Sam | 1 | 15 
Sam | 2 |  6 
Bob | 1 |  9 
Bob | 2 | 11 

В чем-то больше, как это:

Name | Value1 | Value2 
Sam |  15 |  6 
Bob |  9 |  11 

Примечание: Я нахожу очень трудное время выяснив название для этого вопроса.

ответ

4

Вы можете использовать опорный элемент для этого в качестве примера. Посмотрите на этот фрагмент кода:

SELECT pvt.Name, pvt.[1] as Value1, pvt.[2] as Value2 
FROM yourTable 
PIVTO (
    MAX(Value) 
    FOR id IN([1],[2]) 
) as pvt 

Вам просто нужно добавлять дополнительные идентификаторы в IN() и SELECT.

Если вам нужен динамический стержень, вы можете использовать этот один над здесь:

DECLARE @sql nvarchar(max), @columnlist nvarchar(max) 

SELECT @columnlist = 
     COALESCE(@columnlist + N',['+CONVERT(nvarchar(max),cols.id)+']', 
      N'['+CONVERT(nvarchar(max),cols.id)+']' 
     ) 
FROM (SELECT DISTINCT id FROM yourTable) as cols 

-- this is your part 
SET @sql = N' 
    SELECT pvt.* 
    FROM yourTable 
    PIVTO (
     MAX(Value) 
     FOR id IN('[email protected]+') 
    ) as pvt' 
EXEC(@sql) 
2

Если вы можете быть уверены в том, что набор будет только когда-либо иметь два значения, и они всегда будут иметь ID либо 1 или 2, вы можете сделать примерно следующее:

CREATE TABLE #Table (Name VARCHAR(5), ID INT, Value INT) 
INSERT INTO #Table VALUES ('Sam', 1, 15), ('Sam', 2, 6), ('Bob', 1, 9), ('Bob', 2, 11) 

SELECT t.Name, 
     t.Value AS Value1, 
     t2.Value AS Value2 
    FROM #Table t 
    INNER JOIN #Table t2 ON t2.Name = t.Name AND t2.ID = 2 
    WHERE t.ID = 1 

DROP TABLE #Table 

Обратите внимание, что временная таблица предназначена только для иллюстрации результата. Важным является заявление SELECT.

Это присоединяет таблицу к себе, чтобы получить значение Value2.

+0

Вам нужно будет переписать этот запрос для добавления/удаления операций присоединения в зависимости от того, сколько значений вы связываете с каждым именем. Я думаю, что стержень будет более надежным решением проблемы в целом, хотя это решение будет достаточно хорошо работать с конкретным примером. – DeadZone

+0

Я согласен с тем, что 'PIVOT' является более подходящим решением, но когда есть только два значения (как указывал OP), это будет работать быстрее. –

+1

Фактически, OP указывало, что «количество идентификаторов может варьироваться для представленных данных», но этот пример «будет иметь ровно 2 значения для имени." – DeadZone

2

Что вам нужно, это запрос PIVOT. В зависимости от того, сколько имен у вас в вашем наборе данных, и знаете ли вы их заранее, вам, вероятно, понадобится «динамический Pivot».

Сводные запросы могут быть немного запутанными. Но вот два примера построения динамического сводного запроса. (2-я один еще один вопрос о переполнении стека, и может быть лучше для вашей ситуации, чем первый.)

T-SQL: Dynamic Pivot on Multiple Columns

T-SQL dynamic pivot

EDIT: Конкретный пример ...

-- DROP TABLE #MyTable 
-- CREATE TABLE #MyTable(name varchar(10), ID int, value int); 

INSERT #MyTable VALUES ('Sam', 1, 15); 
INSERT #MyTable VALUES ('Sam', 2, 6); 
INSERT #MyTable VALUES ('Bob', 1, 9); 
INSERT #MyTable VALUES ('Bob', 2, 11); 
-- INSERT #MyTable VALUES ('Sam', 3, 1); 
-- INSERT #MyTable VALUES ('Bob', 3, 2); 


DECLARE @cols NVARCHAR(2000) 
DECLARE @query NVARCHAR(4000) 

SELECT @cols = STUFF((SELECT DISTINCT TOP 100 PERCENT 
           '],[' + CONVERT(varchar(5), t.ID) 
         FROM #MyTable AS t 
         --ORDER BY '],[' + t.ID 
         FOR XML PATH('') 
        ), 1, 2, '') + ']' 

--SELECT @cols 

SET @query = N'SELECT name,'+ @cols +' FROM 
(SELECT t1.name, t1.ID, t1.Value FROM #MyTable AS t1) p 
PIVOT (MAX([Value]) FOR ID IN ('+ @cols +')) 
AS pvt;' 

EXECUTE(@query) 
+0

Это похоже на то, что я искал. Я попытался использовать этот бит кода с 3 и 4 значениями для имени, и он отлично работал. Благодаря @DeadZone –

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