使Pivot Columns动态化

时间:2016-09-26 13:33:14

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

我有以下查询返回一个每个应用程序总错误的数据透视表。但问题是我需要手动指定表列。我想设置@StartDate和@EndDate,查询会自动将列构建为Date + 1

这是查询

set transaction isolation level read uncommitted;

WITH BaseQuery AS (
SELECT 
CASE [Application]  WHEN 'EM_ws.XYZ.com' THEN 'XYZ'
                    WHEN 'XYZ'          THEN 'XWZ'
                    WHEN 'EM_WDE.api'           THEN 'WDE'
                    WHEN 'EM_MMCS'          THEN 'MMCS'
                    ELSE 'UnknownBounce' END AS Application,
CAST ([Log_Time] AS date) AS Date,
COUNT([Message]) AS NBRMSG
FROM
    [GLOBAL_LOG].[dbo].[YSHD_Application_Log] WITH (NOLOCK)
WHERE
      [Log_Time] BETWEEN '2016-09-20 00:00:00' AND '2016-09-22 23:59:00'
      AND
      ([Message] LIKE 'E_%' OR [Message] LIKE '(500) - 1 - Internal Server Error' OR [Message] LIKE ' - {"result":"error","message":"Internal Error","code":600}')    
      AND
    1=1
GROUP BY [Application],[Log_Time]
)
SELECT * FROM BaseQuery
PIVOT (SUM(NBRMSG) FOR Date IN ([2016-09-20],[2016-09-21],[2016-09-22])
) AS PVT

经过一些研究,我尝试了以下但是收到了错误信息

  

" VALUE"不是有效的函数,属性或字段。

set transaction isolation level read uncommitted;

DECLARE @cols   AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX),
        @StartDate DATE,
        @EndDate DATE

SET     @StartDate='2016-09-20'
SET     @EndDate='2016-09-22'


CREATE TABLE #t
   (
     WDate SMALLDATETIME
   )


;WITH d(DATE) AS (
  SELECT cast(@StartDate AS datetime)
  UNION ALL
  SELECT DATE + 1
  FROM d
  WHERE DATE < @EndDate
  )
  INSERT INTO #t SELECT  d.DATE FROM d

SELECT      @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(wd.WDate) 
                FROM #t wd
                FOR XML PATH(''), TYPE
                ).VALUE('.', 'NVARCHAR(MAX)') 
            ,1,1,'')
--PRINT @cols

SET @query = '
SELECT * FROM (
SELECT 
CASE [Application]  WHEN ''EM_ws.XYZ.com'' THEN ''XYZ''
                    WHEN ''XYZ''            THEN ''XWZ''
                    WHEN ''EM_WDE.api''         THEN ''WDE''
                    WHEN ''EM_MMCS''            THEN ''MMCS''
                    ELSE ''UnknownBounce'' END AS Application,
CAST ([Log_Time] AS date) AS CDate,
COUNT([Message]) AS NBRMSG
FROM
    [GLOBAL_LOG].[dbo].[YSHD_Application_Log] WITH (NOLOCK)
WHERE
      [Log_Time] BETWEEN @StartDate AND @EndDate
      AND
      ([Message] LIKE ''E_%'' OR [Message] LIKE ''(500) - 1 - Internal Server Error'' OR [Message] LIKE '' - {"result":"error","message":"Internal Error","code":600}'')    
      AND
    1=1
GROUP BY [Application],[Log_Time]
) src

PIVOT 
(
    SUM(NBRMSG) 
    FOR src.CDate IN (' + @cols + ')
) AS PVT'

PRINT (@query)
execute(@query)

drop table #t

我更新了查询,现在它给出了以下错误..

  

消息102,级别15,状态1,行14错误的语法接近&#39; WDate   DATE&#39;

set transaction isolation level read uncommitted;

DECLARE @cols   AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX),
        @StartDate DATE,
        @EndDate DATE

SET     @StartDate='2016-09-20'
SET     @EndDate='2016-09-22'


CREATE TABLE #t
   (
     WDate DATE
   )


;WITH d(DATE) AS (
  SELECT CAST(@StartDate AS DATE)
  UNION ALL
  SELECT DATEADD (DAY,1,DATE)
  FROM d
  WHERE DATE < @EndDate
  )
  INSERT INTO #t SELECT  d.DATE FROM d

SELECT  @cols = STUFF(
               (SELECT DISTINCT ',' + QUOTENAME(wd.WDate) 
                FROM #t wd
                FOR XML PATH('')) 
              ,1,1,'')
--PRINT @cols

SET @query = '
SELECT * FROM (
SELECT 
CASE [Application]  WHEN ''EM_ws.campaigner.com'' THEN ''CAMPAIGNER''
                    WHEN ''Campaigner''         THEN ''CAMPAIGNER''
                    WHEN ''EM_ctgy.api''            THEN ''CTGY''
                    WHEN ''EM_EDRestApi''           THEN ''ED''
                    ELSE ''UnknownBounce'' END AS Application,
CAST ([Log_Timestamp] AS DATE) AS DATE,
COUNT([Message]) AS NBRMSG
FROM
    [GENERIC_LOGGER].[dbo].[Campaigner_Application_Log] WITH (NOLOCK)
WHERE
      [Log_Timestamp] BETWEEN @StartDate AND DATEADD (DAY,1,@EndDate)
      AND
      ([Message] LIKE ''E_%'' OR [Message] LIKE ''(500) - 1 - Internal Server Error'' OR [Message] LIKE '' - {"result":"error","message":"Internal Error","code":600}'')    
      AND
    1=1
GROUP BY [Application],[Log_Time]
) src

PIVOT 
(
    SUM(NBRMSG) 
    FOR src.CDate IN (' + @cols + ')
) AS PVT'

--PRINT (@query)
EXECUTE(@query)

--DROP TABLE #t


--SELECT * FROM #t

根据Sean的推荐,这是一个重新创建原始表的DDL:

CREATE TABLE Campaigner_Application_Log(
   LOGID         INTEGER  NOT NULL PRIMARY KEY 
  ,Log_Timestamp DATETIME  NOT NULL
  ,Application   VARCHAR(30) NOT NULL
  ,Message       VARCHAR(60) NOT NULL
);
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252152,'2016-09-20 00:06:22.100','EM_ws.campaigner.com','E_1.1.18_INTERNAL-ERROR - An internal error occurred.');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252153,'2016-09-20 00:06:22.973','EM_ws.campaigner.com','E_1.1.18_INTERNAL-ERROR - An internal error occurred.');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252154,'2016-09-20 00:26:47.393','EM_ws.campaigner.com','E_1.1.18_INTERNAL-ERROR - An internal error occurred.');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252155,'2016-09-20 00:31:44.723','EM_EDRestApi','(500) - 1 - Internal Server Error');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252156,'2016-09-20 00:07:21.740','EM_ws.campaigner.com','E_1.1.18_INTERNAL-ERROR - An internal error occurred.');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252157,'2016-09-20 00:31:28.487','EM_EDRestApi','(500) - 1 - Internal Server Error');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252158,'2016-09-20 00:31:38.740','EM_EDRestApi','(500) - 1 - Internal Server Error');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252159,'2016-09-20 00:48:12.717','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.InvalidOperationE');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252160,'2016-09-20 00:48:24.200','EM_ws.campaigner.com','E_1.1.18_INTERNAL-ERROR - An internal error occurred.');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252161,'2016-09-20 00:34:26.130','EM_ws.campaigner.com','E_1.1.18_INTERNAL-ERROR - An internal error occurred.');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252162,'2016-09-20 12:38:06.820','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Web.HttpException');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252163,'2016-09-20 12:45:25.997','EM_ws.campaigner.com','E_1.1.18_INTERNAL-ERROR - An internal error occurred.');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252164,'2016-09-20 12:33:59.053','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Web.HttpRequestVa');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252165,'2016-09-20 12:36:21.290','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Web.HttpException');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252166,'2016-09-21 03:08:25.317','EM_ws.campaigner.com','E_1.1.18_INTERNAL-ERROR - An internal error occurred.');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252167,'2016-09-21 03:08:25.457','EM_ws.campaigner.com','E_1.1.18_INTERNAL-ERROR - An internal error occurred.');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252168,'2016-09-21 03:12:08.100','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Web.HttpException');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252169,'2016-09-21 03:12:10.083','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Web.HttpException');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252170,'2016-09-21 03:12:25.820','EM_ws.campaigner.com','E_1.1.18_INTERNAL-ERROR - An internal error occurred.');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252171,'2016-09-21 03:02:21.043','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Web.HttpException');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252172,'2016-09-21 03:30:12.643','EM_EDRestApi','(500) - 1 - Internal Server Error');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252173,'2016-09-21 03:21:00.590','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Web.HttpException');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252174,'2016-09-21 03:24:20.077','EM_ws.campaigner.com','E_1.1.18_INTERNAL-ERROR - An internal error occurred.');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252175,'2016-09-21 03:24:20.123','EM_ws.campaigner.com','E_1.1.18_INTERNAL-ERROR - An internal error occurred.');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252176,'2016-09-21 03:28:56.487','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Web.HttpException');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252177,'2016-09-21 03:30:48.003','EM_EDRestApi','(500) - 1 - Internal Server Error');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252178,'2016-09-21 02:40:09.317','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.InvalidOperationE');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252179,'2016-09-21 02:40:23.477','EM_ws.campaigner.com','E_1.1.18_INTERNAL-ERROR - An internal error occurred.');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252180,'2016-09-21 02:43:46.840','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Web.HttpException');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252181,'2016-09-21 03:00:23.263','EM_ws.campaigner.com','E_1.1.18_INTERNAL-ERROR - An internal error occurred.');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252182,'2016-09-21 03:06:51.237','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Web.HttpException');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252183,'2016-09-21 03:13:48.290','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Web.HttpException');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252184,'2016-09-21 03:17:22.323','EM_ws.campaigner.com','E_1.1.18_INTERNAL-ERROR - An internal error occurred.');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252185,'2016-09-21 03:30:02.190','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Web.HttpException');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252186,'2016-09-21 03:35:04.397','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Web.HttpException');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252187,'2016-09-21 03:31:13.127','EM_EDRestApi','(500) - 1 - Internal Server Error');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252188,'2016-09-21 03:33:21.207','EM_ws.campaigner.com','E_1.1.18_INTERNAL-ERROR - An internal error occurred.');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252189,'2016-09-21 03:38:20.537','EM_ws.campaigner.com','E_1.1.18_INTERNAL-ERROR - An internal error occurred.');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252190,'2016-09-21 21:17:18.290','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Web.HttpException');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252191,'2016-09-21 21:17:18.290','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Web.HttpException');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252192,'2016-09-21 21:17:18.290','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Web.HttpException');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252193,'2016-09-22 23:30:26.953','EM_EDRestApi','(500) - 1 - Internal Server Error');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252194,'2016-09-21 21:17:18.290','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Web.HttpException');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252195,'2016-09-22 23:30:44.343','EM_EDRestApi','(500) - 1 - Internal Server Error');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252196,'2016-09-22 23:31:32.673','EM_EDRestApi','(500) - 1 - Internal Server Error');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252197,'2016-09-22 23:31:33.030','EM_ws.campaigner.com','E_1.1.18_INTERNAL-ERROR - An internal error occurred.');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252198,'2016-09-22 10:59:02.030','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Web.HttpException');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252199,'2016-09-22 23:31:38.970','EM_EDRestApi','(500) - 1 - Internal Server Error');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252200,'2016-09-21 21:18:52.357','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Web.HttpException');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252201,'2016-09-21 21:20:25.687','EM_ws.campaigner.com','E_1.1.18_INTERNAL-ERROR - An internal error occurred.');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252202,'2016-09-21 21:21:58.937','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Threading.ThreadA');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252203,'2016-09-22 23:31:53.173','EM_EDRestApi','(500) - 1 - Internal Server Error');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252204,'2016-09-22 23:33:30.953','EM_ws.campaigner.com','E_1.1.18_INTERNAL-ERROR - An internal error occurred.');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252205,'2016-09-22 12:52:06.343','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Web.HttpException');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252206,'2016-09-22 12:52:15.530','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Web.HttpException');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252207,'2016-09-22 12:55:26.090','EM_ws.campaigner.com','E_1.1.18_INTERNAL-ERROR - An internal error occurred.');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252208,'2016-09-22 12:56:21.513','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Threading.ThreadA');
INSERT INTO Campaigner_Application_Log(LOGID,Log_Timestamp,Application,Message) VALUES (1252209,'2016-09-22 12:56:34.530','Campaigner','E_1.1.2_UNCLASSIFIED-ERROR - System.Web.HttpException');

我想要的结果如下

Sample result

1 个答案:

答案 0 :(得分:0)

这个片段你不需要将字符串转换为XML并返回字符串。刚

SELECT  @cols = STUFF(
               (SELECT DISTINCT ',' + QUOTENAME(wd.WDate) 
                FROM #t wd
                FOR XML PATH('')) 
              ,1,1,'')

编辑

在脚本的第二部分使用sp_executesql,它允许更清晰的代码,参见示例

DECLARE  @query  AS NVARCHAR(MAX),
        @StartDate DATE,
        @EndDate DATE;

SET     @StartDate='2016-09-20';
SET     @EndDate='2016-09-30';

SET @query = 'SELECT 1 WHERE getdate() BETWEEN @p1 AND @p2';

DECLARE @paramDefinition nvarchar(max) = N'@p1 DATE, @p2 DATE';

EXEC sp_executesql @query, @paramDefinition, @p1=@StartDate, @p2=@EndDate;

或者在字面上将值插入查询

DECLARE  @query  AS NVARCHAR(MAX),
        @StartDate DATE,
        @EndDate DATE;

SET     @StartDate='2016-09-20';
SET     @EndDate='2016-09-30';
SET @query = 'SELECT 1 WHERE getdate() BETWEEN ''' + cast(@StartDate as varchar(20)) +''' AND ''' + cast(@EndDate as varchar(20)) + ''''
SELECT @query;  
-- SELECT 1 WHERE getdate() BETWEEN '2016-09-20' AND '2016-09-30' 
EXEC (@query);