sql >> Database teknologi >  >> RDS >> Sqlserver

SQL Server 2008 R2 - Dynamic Pivot/Unpivot med (flytte) datoer

Du skal først UNPIVOT vores kolonner og brug DENSE_RANK() for at give dig noget at dreje på senere. Indsæt dette resultat i en midlertidig tabel, så du kan få en kommasepareret liste over DESNSE_RANK kolonner. Opret derefter en UNIONDay og Date er en del af samme kolonne som det, der var upivot. Dette kan sættes i en global temp-tabel til brug i den dynamiske SQL. Opret en variabel, der gemmer listen over kolonner og bygger den dynamiske SQL og eksekver den.

Et komplet eksempel (du skal selvfølgelig ikke droppe PhaseFlowChart tabel)

-- pre-cleanup
IF OBJECT_ID('[dbo].[PhaseFlowChart]') IS NOT NULL
    DROP TABLE [dbo].[PhaseFlowChart]
GO

IF OBJECT_ID('tempdb..#tmp') IS NOT NULL
    DROP TABLE #tmp
GO

IF OBJECT_ID('tempdb..##tmp') IS NOT NULL
    DROP TABLE ##tmp
GO

-- setup table and data
CREATE TABLE [dbo].[PhaseFlowChart](
    [pfckey] [int] NULL,
    [hourlykey] [bigint] NULL,
    [daykey] [bigint] NULL,
    [weekkey] [int] NULL,
    [monthkey] [int] NULL,
    [bbkey] [int] NULL,
    [Day] [varchar](100) NULL,
    [Date] [varchar](100) NULL,
    [Bull Bear Gap] [varchar](100) NULL,
    [Monthly] [varchar](100) NULL,
    [Weekly] [varchar](100) NULL,
    [Daily] [varchar](100) NULL,
    [Hour 1] [varchar](100) NULL,
    [Hour 2] [varchar](100) NULL,
    [Hour 3] [varchar](100) NULL,
    [Hour 4] [varchar](100) NULL,
    [Hour 5] [varchar](100) NULL,
    [Hour 6] [varchar](100) NULL,
    [Hour 7] [varchar](100) NULL
) ON [PRIMARY]

INSERT INTO [dbo].PhaseFlowChart 
    ([Day], [Date], [Bull Bear Gap], Monthly, Weekly, Daily, 
        [Hour 1], [Hour 2], [Hour 3], [Hour 4], [Hour 5], [Hour 6], [Hour 7])
VALUES
('MON', '20130101', 'P1', 'P1', 'P1', 'P1', 'P1', 'P1', 'P1', 'P1', 'P1', 'P1', 'P1'),
('TUE', '20130102', 'P2', 'P2', 'P2', 'P2', 'P2', 'P2', 'P2', 'P2', 'P2', 'P2', 'P2'),
('WED', '20130103', 'P3', 'P3', 'P3', 'P3', 'P3', 'P3', 'P3', 'P3', 'P3', 'P3', 'P3'),
('THU', '20130104', 'P4', 'P4', 'P4', 'P4', 'P4', 'P4', 'P4', 'P4', 'P4', 'P4', 'P4'),
('FRI', '20130105', 'P5', 'P5', 'P5', 'P5', 'P5', 'P5', 'P5', 'P5', 'P5', 'P5', 'P5'),
('SAT', '20130106', 'P6', 'P6', 'P6', 'P6', 'P6', 'P6', 'P6', 'P6', 'P6', 'P6', 'P6'),
('SUN', '20130107', 'P7', 'P7', 'P7', 'P7', 'P7', 'P7', 'P7', 'P7', 'P7', 'P7', 'P7')
GO

-- unpivot the columns into 'categories'
SELECT [Day], [Date], [Value], [Category], 
    DENSE_RANK() OVER (ORDER BY CAST([Date] AS DATE)) dr 
INTO #tmp
FROM PhaseFlowChart pfc
UNPIVOT (
    Value FOR Category IN ([Bull Bear Gap], Monthly, Weekly, Daily, 
                            [Hour 1], [Hour 2], [Hour 3], [Hour 4], 
                                [Hour 5], [Hour 6], [Hour 7])

) upiv

-- create a global temp table for use later
SELECT *
INTO ##tmp
FROM (
      -- union data into single category column
    SELECT 'Day' Category, [Day] Value, dr, 1 o FROM #tmp
    UNION ALL
    SELECT 'Date' Category, [Date] Value, dr, 2 o FROM #tmp
    UNION ALL
    SELECT [Category], Value, dr, 3 o FROM #tmp
) t

-- get a comma seperated list of columns for the PIVOT
DECLARE @cols VARCHAR(MAX) = 
STUFF(CAST((SELECT ',' + QUOTENAME(dr)
       FROM (
           SELECT DISTINCT dr
           FROM #tmp
       ) t
       ORDER BY dr
       FOR XML PATH(''), TYPE
      ) AS VARCHAR(MAX)),1,1,'')

-- create and execute the sql
DECLARE @sql VARCHAR(MAX) = '
    SELECT Category, ' + @cols + '
    FROM ##tmp
    PIVOT (
        MAX([Value])
        FOR dr IN (' + @cols + ')
    ) piv   
      ORDER BY o, CASE Category 
                    WHEN ''Daily'' THEN 4
                    WHEN ''Weekly'' THEN 3
                    WHEN ''Monthly'' THEN 2
                    WHEN ''Bull Bear Gap'' THEN 1
                    ELSE 5 END, Category
'

EXEC(@sql)



  1. Hvordan indsætter man data i MySQL med automatisk forøget primærnøgle?

  2. Hvordan udføres mysql-script med variabler ved hjælp af PHP::PDO?

  3. Hvad er BIN$... tabellerne i Oracles ALL_TAB_COLUMNS tabel?

  4. HVIS IKKE FINDER i trigger