Sql 使轴列成为动态的

Sql 使轴列成为动态的,sql,sql-server,sql-server-2008,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 'XY

我有下面的查询,它返回一个透视表,每个应用程序都有总错误。但问题是我需要手动指定表列。我想设置@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
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);
经过一些研究,我尝试了下面的方法,但我收到了一条错误消息

“值”不是有效的函数、属性或字段

我想要的结果如下
A在这个片段中,您不需要将字符串转换为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;
或者,直接将值插入查询中

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
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);

在这个片段中,您不需要将字符串转换为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;
或者,直接将值插入查询中

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
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);

你能为日志表和一些样本数据提供ddl吗?我假设它是一个日志表…因此表的名称。所以你想让我给你发送ddl来重新创建这个表和样本数据吗?我不能在这里运行任何东西,除非我有正确的表?在继续到处散布NOLOCK提示之前,您可能还想看看这篇文章。谢谢@SeanLange我添加了ddl你能为日志表和一些样本数据提供ddl吗?我假设它是一个日志表…因此表的名称。所以你想让我给你发送ddl来重新创建这个表和样本数据吗?除非我有正确的表,否则我不能在这里运行任何东西?在继续到处散布NOLOCK提示之前,您可能还想看看这篇文章。谢谢@SeanLange我添加了DDL它成功了!我不明白为什么我现在会遇到这个错误。我必须声明标量变量“@StartDate”,因为EXECUTE(@query)在它自己的上下文中运行,而它对其他上下文中的变量一无所知。按字面意思插入它们,
SET@query=”…其中[Log_Time]介于“+cast”(@StartDate as varchar(20))+””和“+cast”(@StartDate as varchar(20))+”…”
谢谢@Serg i将查询更改为:
[Log_Timestamp]介于“+cast”(@StartDate as DATE)+”和DATEADD(DAY,1)之间,+cast(@EndDate as DATE)+”
现在我遇到了这个错误:*从字符串转换日期和/或时间时,转换失败**成功了!我不明白为什么我现在会遇到这个错误。我必须声明标量变量“@StartDate”,因为EXECUTE(@query)在它自己的上下文中运行,而它对其他上下文中的变量一无所知。按字面意思插入它们,
SET@query=”…其中[Log_Time]介于“+cast”(@StartDate as varchar(20))+””和“+cast”(@StartDate as varchar(20))+”…”
谢谢@Serg i将查询更改为:
[Log_Timestamp]介于“+cast”(@StartDate as DATE)+”和DATEADD(DAY,1)之间,+cast(@EndDate as DATE)+”
现在我遇到了这个错误:*从字符串转换日期和/或时间时,转换失败**