2012-03-07 3 views
1

Я никогда не использовал SQL Pivot, но я думаю, что теперь у меня есть шанс. Проблема в том, что я действительно не знаю, как это сделать. Я читал документацию, но, похоже, результат, который я хочу, может быть немного сложным, и я могу с трудом обрабатывать простые опорные точки на этом этапе.SQL Sever Pivot Many Columns

У меня есть эта таблица

Create table dataTable (dataID int, containerID int) 

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

Create table pivotTable (DataID int, Container1 bit, Container2 bit, ...ContainerN bit) 

Где каждый DataID из DataTable становится строкой, и бит -значение для ConatinerN равно 1, если кортеж {DataID, ContainerN} существует в dataTable, и 0, если он нет. Есть 480 ContainerID, поэтому я бы не указал их вручную, но могу, если это необходимо.

Спасибо за помощь!

+2

Динамический пример поворота здесь: http://stackoverflow.com/questions/2209700/how-to-use-pivot-in-sql- server-2005-stored-procedure-join-two-views –

ответ

2

Может быть что-то вроде этого:

Тестовые данные

Create table dataTable (dataID int, containerID int) 

INSERT INTO dataTable 
VALUES 
    (1,1), 
    (2,1), 
    (3,3), 
    (4,2) 

Уникальные колонки

DECLARE @cols VARCHAR(MAX) 
DECLARE @colsWithIsNull VARCHAR(MAX) 
;WITH CTE 
AS 
(
    SELECT 
     ROW_NUMBER() OVER(PARTITION BY containerID ORDER BY containerID) AS RowNbr, 
     CAST(containerID AS VARCHAR(100)) AS containerID 
    FROM 
     dataTable 
) 
SELECT @cols = COALESCE(@cols + ','+QUOTENAME('Container'+containerID), 
        QUOTENAME('Container'+containerID)), 
     @colsWithIsNull= COALESCE(@colsWithIsNull + ',CAST(ISNULL('+QUOTENAME('Container'+containerID)+',0) AS BIT) AS '+QUOTENAME('Container'+containerID), 
        'CAST(ISNULL('+QUOTENAME('Container'+containerID)+',0) AS BIT) AS '+QUOTENAME('Container'+containerID)) 
FROM 
    CTE 
WHERE 
    CTE.RowNbr=1 

Динамический поворотный

DECLARE @query NVARCHAR(4000)= 
N'SELECT 
    dataID, 
    '[email protected]+' 
FROM 
(
    SELECT 
     ''Container''+CAST(dataTable.containerID AS VARCHAR(100)) AS ContainerText, 
     1 AS isContainer, 
     dataTable.dataID 
    FROM 
     dataTable 
) AS p 
PIVOT 
(
    MAX(isContainer) 
    FOR ContainerText IN ('[email protected]+') 
) AS pvt' 

EXECUTE(@query) 

В моем случае я понизит тестовую таблицу:

DROP TABLE dataTable 
+0

Бинго. Я уже получил данные, которые я хотел получить от SSRS, но это именно то, что я искал. Благодарю. – Colin

+0

Без проблем .. Рад помочь .. – Arion

1

Отсчет данных, подобных этому, не имеет большого смысла. Это лучше сделать на уровне доступа к данным приложения. Как вы сказали, вы должны возвращаться набор данных, как это ...

{ DataID INT, ContainerNumber INT } 

Чтобы сделать вашу жизнь проще, вернуть только контейнеры, которые имеют 1 в колонке, а затем заполнить пробелы.

+0

Я не уверен, что я следую. Данные, которые у меня есть, уже находятся в формате '{DataID INT, ContainerNumber INT}', но это не то, что я хочу. – Colin

+0

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

+0

Ну, это не так, это набор данных ad-hoc, скремблированный вручную. Тем не менее, несмотря на то, что хранение таблицы из примерно 500 столбцов, где подавляющее большинство значений равно нулю, кажется довольно неэффективным, а также невероятно громоздким в основном за исключением этого разового отчета. Кроме того, я бы предпочел не использовать курсор, так как я чувствую, что это именно то, что делает функция поворота, и я хотел бы узнать, как его использовать. – Colin