SQL Server Pivot много столбцов - PullRequest
1 голос
/ 07 марта 2012

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

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

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 идентификаторов контейнеров, поэтому я бы не стал указывать их все вручную, но могу при необходимости.

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

Ответы [ 2 ]

2 голосов
/ 07 марта 2012

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

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

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,
    '+@colsWithIsNull+'
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 ('+@cols+')
) AS pvt'

EXECUTE(@query)

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

DROP TABLE dataTable
1 голос
/ 07 марта 2012

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

{ DataID INT, ContainerNumber INT }

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

...