SQL-запрос - почти как сводная таблица? - PullRequest
0 голосов
/ 30 марта 2012

Еще один глупый вопрос, касающийся сценария SQL.

Данные, такие как:

FieldKey    DocumentKey FieldId FieldValue
1   00001c55-aab3-4df8-a07e-8eac162fa075    TITLE   Mass Import 18355
2   00001c55-aab3-4df8-a07e-8eac162fa075    1   00001c55-aab3-4df8-a07e-8eac162fa075
3   00001c55-aab3-4df8-a07e-8eac162fa075    2   9F-2F-CF-76-27-E7-5B-C9-27-CE-23-45-68-3F-E2-89
4   00001c55-aab3-4df8-a07e-8eac162fa075    3   18355
5   00001c55-aab3-4df8-a07e-8eac162fa075    4   94-3C-84-B1-6A-AA-FD-25-F1-C0-D2-43-CD-D3-57-D6
6   00001c55-aab3-4df8-a07e-8eac162fa075    5   Created by C# mass import
7   00002205-00D3-4495-B65A-A7B1FD2AE7F2    TITLE   Mass Import 1494780
8   00002205-00D3-4495-B65A-A7B1FD2AE7F2    1   00002205-00D3-4495-B65A-A7B1FD2AE7F2
9   00002205-00D3-4495-B65A-A7B1FD2AE7F2    2   870386312
10  00002205-00D3-4495-B65A-A7B1FD2AE7F2    3   1494780
11  00002205-00D3-4495-B65A-A7B1FD2AE7F2    4   -1929051324
13  00002342-6de0-4110-b576-fd32f96b2858    TITLE   Mass Import 387008
14  00002342-6de0-4110-b576-fd32f96b2858    1   00002342-6de0-4110-b576-fd32f96b2858
15  00002342-6de0-4110-b576-fd32f96b2858    2   B0-CB-DF-ED-48-DC-C4-E8-B0-6F-1B-1D-81-2D-6D-51
16  00002342-6de0-4110-b576-fd32f96b2858    3   387008

Со структурой стола:

[FieldKey] [bigint] IDENTITY(1,1) NOT NULL,
[DocumentKey] [char](36) NOT NULL,
[FieldId] [varchar](10) NOT NULL,
[FieldValue] [varchar](255) NOT NULL

Каков наилучший способ перевернуть эти данные по горизонтали? В идеале:

DocumentKey                             TITLE    1    2    3    4    5
00001c55-aab3-4df8-a07e-8eac162fa075    mytitle  val1 val2 val3 val4 val5
00002205-00D3-4495-B65A-A7B1FD2AE7F2    mytitle2 val6 val7 val8 val9
00002342-6de0-4110-b576-fd32f96b2858    mytitle3 vl10 vl11 vl12

Я думал, что сводная таблица может работать, и она близка, но проблема в том, что мне не нужна агрегация, которая требуется для сводной SQL Я просто хочу перевернуть данные. Количество столбцов (1-5 плюс TITLE в моем примере) может быть где угодно между TITLE плюс 1-30.

Может быть, я просто плотный, но любые идеи будут оценены.

Ответы [ 2 ]

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

Я думаю, что вы на правильном пути с PIVOT.Вы будете иметь агрегат в столбце значений.Но, как вы говорите, у вас будет 1-30 столбцов плюс заголовок столбца.Для этого требуется динамический круг

Вот предложение (только для SQL Server 2005 +):

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

CREATE TABLE Table1
(
    [FieldKey] [bigint] NOT NULL,
    [DocumentKey] [char](36) NOT NULL,
    [FieldId] [varchar](10) NOT NULL,
    [FieldValue] [varchar](255) NOT NULL
)
INSERT INTO Table1
VALUES
    (1,'00001c55-aab3-4df8-a07e-8eac162fa075','TITLE','Mass Import 18355'),
    (2,'00001c55-aab3-4df8-a07e-8eac162fa075','1','00001c55-aab3-4df8-a07e-8eac162fa075'),
    (3,'00001c55-aab3-4df8-a07e-8eac162fa075','2','9F-2F-CF-76-27-E7-5B-C9-27-CE-23-45-68-3F-E2-89'),
    (4,'00001c55-aab3-4df8-a07e-8eac162fa075','3','18355'),
    (5,'00001c55-aab3-4df8-a07e-8eac162fa075','4','94-3C-84-B1-6A-AA-FD-25-F1-C0-D2-43-CD-D3-57-D6'),
    (6,'00001c55-aab3-4df8-a07e-8eac162fa075','5','Created by C# mass import'),
    (7,'00002205-00D3-4495-B65A-A7B1FD2AE7F2','TITLE','Mass Import 1494780'),
    (8,'00002205-00D3-4495-B65A-A7B1FD2AE7F2','1','00002205-00D3-4495-B65A-A7B1FD2AE7F2'),
    (9,'00002205-00D3-4495-B65A-A7B1FD2AE7F2','2','870386312'),
    (10,'00002205-00D3-4495-B65A-A7B1FD2AE7F2','3','1494780'),
    (11,'00002205-00D3-4495-B65A-A7B1FD2AE7F2','4','-1929051324'),
    (13,'00002342-6de0-4110-b576-fd32f96b2858','TITLE','Mass Import 387008'),
    (14,'00002342-6de0-4110-b576-fd32f96b2858','1','00002342-6de0-4110-b576-fd32f96b2858'),
    (15,'00002342-6de0-4110-b576-fd32f96b2858','2','B0-CB-DF-ED-48-DC-C4-E8-B0-6F-1B-1D-81-2D-6D-51'),
    (16,'00002342-6de0-4110-b576-fd32f96b2858','3','387008')

Найдите уникальные столбцы

DECLARE @cols VARCHAR(MAX)
;WITH CTE
AS
(
    SELECT
        ROW_NUMBER() OVER(PARTITION BY Table1.FieldId 
                              ORDER BY Table1.FieldId) AS RowNbr,
        Table1.*
    FROM
        Table1
)
SELECT @cols=STUFF
(
    (
        SELECT 
            ',' +QUOTENAME(CTE.FieldId)
        FROM
            CTE
        WHERE
            CTE.RowNbr=1
        ORDER BY 
            LEN(CTE.FieldId) DESC,
            CTE.FieldId
        FOR XML PATH('')
    )
,1,1,'')

Нам нужно сделать так, чтобы TITLE был первым.FOR XML PATH предназначен для объединения столбцов.

Динамический круг

DECLARE @query NVARCHAR(4000)=
N'SELECT
    *
FROM
(
    SELECT
        Table1.DocumentKey,
        Table1.FieldId,
        Table1.FieldValue
    FROM
        Table1
) AS p
PIVOT
(
    MAX(FieldValue)
    FOR FieldId IN('+@cols+')
) AS p'
EXECUTE(@query)

Очистить себя (не требуется)

DROP TABLE Table1
2 голосов
/ 30 марта 2012

Если вы используете SQL Server 2005+, вы можете использовать оператор PIVOT .

select [DocumentKey], [TITLE], [1], [2], [3], [4], [5] 
from (select [DocumentKey], FieldId, FieldValue from TableName) t
    pivot (max(FieldValue) for FieldID in ([TITLE], [1], [2], [3], [4], [5])) as pvt
order by [DocumentKey]

Вам потребуется добавить дополнительные столбцы, 6 - 30.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...