SQL Dynamic Pivot Group By

时间:2017-01-02 16:01:59

标签: sql sql-server sql-server-2008 tsql

我无法按动态数据透视中的代码进行分组。我需要按照ZONE表中定义的代码区进行分组,如下所示。我需要用group by显示不同的代码。一些代码有多个zone_id,因此,我需要合并它们。我正在使用SQL 2008。

ZONE_ID SITE_ID     ZONE_NAME             CODE
197      103        ADANA CADDE CAM2    M01001
180      103        ADANA CADDE CAM1    M01001

Results

Declare @Date1 date = GetDate()


IF OBJECT_ID('tempdb..#Dates') IS NOT NULL
drop table #Dates


SELECT DISTINCT CONVERT(VARCHAR,START_TIME,106) AS [Date]
INTO #Dates
FROM dbo.DIRECTIONAL_METRIC
WHERE CAST(START_TIME as DATE) >=CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(@Date1)-1),@Date1),101)
and CAST(START_TIME as DATE) <= @Date1
AND DATEPART(HOUR,START_TIME) BETWEEN 9 AND 23
order by [Date]

Declare @SQL varchar(max) = Stuff((Select Distinct ',' + QuoteName(convert(varchar,[Date],106)) 
                                   From   #Dates 
                                   Order by 1 For XML Path('')
                                  ),1,1,'') 

Select  @SQL = N'

Declare @Date1 DATE
SELECT @Date1 = GetDate()


SELECT [CODE],' + @SQL + ',[Grand Total Enter],[Grand Total Exit] 
FROM  
(
        SELECT [CODE]
              ,[Date] = CONVERT(VARCHAR, START_TIME, 106)
              ,[NUM_TO_ENTER] 
              ,[Grand Total Enter] = (SELECT SUM(NUM_TO_ENTER) FROM DIRECTIONAL_METRIC WHERE Zone_ID=A.Zone_ID AND
                            CAST(START_TIME AS DATE) >='''+CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(@Date1)-1),@Date1),101)+'''AND CAST(START_TIME AS DATE) <='''+cast(@Date1 as varchar(10))+'''
                            AND DATEPART(HOUR,START_TIME)BETWEEN 9 AND 23)
              ,[Grand Total Exit] =(SELECT SUM(NUM_TO_EXIT)  FROM DIRECTIONAL_METRIC Where Zone_ID=A.Zone_ID AND 
                            CAST(START_TIME AS DATE) >='''+CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(@Date1)-1),@Date1),101)+''' AND CAST(START_TIME AS DATE) <='''+cast(@Date1 as varchar(10))+'''
                            AND DATEPART(HOUR,START_TIME)BETWEEN 9 AND 23)

FROM    DIRECTIONAL_METRIC A INNER JOIN ZONE Z ON Z.ZONE_ID = A.ZONE_ID
        WHERE CAST(START_TIME as DATE) >=CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(@Date1)-1),@Date1),101)
        and CAST(START_TIME as DATE) <= @Date1
        AND DATEPART(HOUR,START_TIME)BETWEEN 9 AND 23
        AND Z.CODE IS NOT NULL
) S
PIVOT 
(
    SUM([NUM_TO_ENTER]) FOR 
    [Date] IN (' + @SQL + ') 
) AS Pvt GROUP BY [CODE] '

Exec(@SQL);

1 个答案:

答案 0 :(得分:1)

问题在于您的派生查询。在您的选择中,并非所有列都在派生表中。分组自动执行sql server(主要考虑数据透视)。

您的支点内部选择:

SELECT 
    [CODE]
    ,[Date] = CONVERT(VARCHAR, START_TIME, 106)
    ,[NUM_TO_ENTER] 
    ,[Grand Total Enter] = (select ...)
    ,[Grand Total Exit] = (select ...)
FROM ...
PIVOT (SUM([NUM_TO_ENTER]) FOR [Date] ...

后台的引擎执行此操作:

SELECT ...
FROM ...
GROUP BY CODE, Grand Total Enter, Grand Total Exit

你必须从qry内删除你的总计。您可以将其移动到外部列选择中或将其分成qry并创建连接。

您也可以使用动态列的+操作来执行sumtotals(01_Jan_2017 + 01_Feb_2017 ...)。

编辑2017-01-04 - 试试这个:

SELECT 
    [CODE]
    ,[Date] = CONVERT(VARCHAR, START_TIME, 106)
    ,[NUM_TO_ENTER]
FROM ...
PIVOT (SUM([NUM_TO_ENTER]) FOR [Date] ...

编辑2017-01-05 - 获得总数:

SELECT 
    [CODE],
    [Grand Total Enter] = (select ...),
    [Grand Total Exit] = (select ...)
FROM (
    SELECT 
        [CODE]
    FROM ...
    GROUP BY [CODE]
) codes

要获得最终输出,请将这两个数据集连接在一起。