【问题标题】:SQL Server Dynamic PivotSQL Server 动态数据透视
【发布时间】:2013-07-04 19:09:53
【问题描述】:

您好,我有一张表,其中包含员工打卡和打卡计时系统中的数据。我正在寻找动态旋转打孔数据列并总计员工班次跨度。但是,我遇到了动态枢轴问题。我检查了其他几个帖子,但我似乎没有得到任何地方。

代码如下:

USE wfcdb
DECLARE @cols as NVARCHAR(MAX),
        @query AS NVARCHAR(MAX);

SELECT @cols = STUFF((SELECT  DISTINCT ',' + QUOTENAME(CONVERT(VARCHAR(10),EVENTDTM,101)) as DATE FROM TIMESHEETITEM  WHERE DATEDIFF(d,EVENTDTM,GetDate()) <7 ORDER BY DATE DESC
                        FOR XML PATH(''), TYPE
                        ).value('.','NVARCHAR(MAX)')
                        ,1,1,'')

Set @query='SELECT EEID, ' + @cols + 'FROM (
SELECT p.PERSONnum as EEID,p.FULLNM as FULLNM, 
convert(varchar(10),ti.EVENTDTM,101) as PunchDate,
DATEDIFF(MINUTE,ti.enddtm,ti.startdtm)/60*-1 AS SPAN
FROM  (((((  
    TIMESHEETITEM ti  With (NoLock) LEFT JOIN  
        PUNCHEVENT pe With (NoLock) ON ti.STARTPUNCHEVENTID = pe.PUNCHEVENTID) LEFT JOIN 
            DATASOURCE ds ON pe.DATASOURCEID = ds.DATASOURCEID) LEFT JOIN 
                CLIENTCONTEXT cc ON ds.CLIENTCONTEXTID = cc.CLIENTCONTEXTID) 
    LEFT JOIN       PUNCHEVENT AS pe1  With (NoLock) ON ti.ENDPUNCHEVENTID = pe1.PUNCHEVENTID) LEFT JOIN 
            DATASOURCE AS ds1 ON pe1.DATASOURCEID = ds1.DATASOURCEID) LEFT JOIN 
                CLIENTCONTEXT AS cc1 ON ds1.CLIENTCONTEXTID = cc1.CLIENTCONTEXTID
    INNER JOIN PERSON p ON ti.EMPLOYEEID = p.PERSONID
    INNER JOIN LABORACCT la1 ON la1.laboracctid = ti.laboracctid
WHERE DATEDIFF(d,ti.EVENTDTM,GetDate()) <7
AND ti.TmShtItemTypeID = 40 
AND (isnull(cc.CLNT,'') + isnull(cc1.CLNT,''))<> '') X
PIVOT
(
    SUM(SPAN) 
    FOR PunchDate in (' + @cols + ')
    ) p'

Execute(@query)

这是我收到的错误消息:

消息 105,第 15 级,状态 1,第 17 行
字符串 ') X 后面的非闭合引号 枢 (.....)p'。
消息 102,第 15 级,状态 1,第 17 行
') X
附近的语法不正确 枢轴(.....

任何帮助将不胜感激。

【问题讨论】:

  • 你需要改这一行:AND (isnull(cc.CLNT,'') + isnull(cc1.CLNT,''))&lt;&gt; '') X,改成这一行:AND (isnull(cc.CLNT,'''') + isnull(cc1.CLNT,''''))&lt;&gt; '''') X

标签: sql sql-server dynamic pivot crosstab


【解决方案1】:

由于您在动态 SQL 中连接空字符串,您需要添加更多单引号:

AND (isnull(cc.CLNT,'''') + isnull(cc1.CLNT,''''))<> '''') X

所以完整的代码是:

DECLARE @cols as NVARCHAR(MAX),
        @query AS NVARCHAR(MAX);

SELECT @cols = STUFF((SELECT  DISTINCT ',' + QUOTENAME(CONVERT(VARCHAR(10),EVENTDTM,101)) as DATE 
                        FROM TIMESHEETITEM  WHERE DATEDIFF(d,EVENTDTM,GetDate()) <7 ORDER BY DATE DESC
                        FOR XML PATH(''), TYPE
                        ).value('.','NVARCHAR(MAX)')
                        ,1,1,'')

Set @query='SELECT EEID, ' + @cols + 'FROM (
SELECT p.PERSONnum as EEID,p.FULLNM as FULLNM, 
convert(varchar(10),ti.EVENTDTM,101) as PunchDate,
DATEDIFF(MINUTE,ti.enddtm,ti.startdtm)/60*-1 AS SPAN
FROM  (((((  
    TIMESHEETITEM ti  With (NoLock) LEFT JOIN  
        PUNCHEVENT pe With (NoLock) ON ti.STARTPUNCHEVENTID = pe.PUNCHEVENTID) LEFT JOIN 
            DATASOURCE ds ON pe.DATASOURCEID = ds.DATASOURCEID) LEFT JOIN 
                CLIENTCONTEXT cc ON ds.CLIENTCONTEXTID = cc.CLIENTCONTEXTID) 
    LEFT JOIN       PUNCHEVENT AS pe1  With (NoLock) ON ti.ENDPUNCHEVENTID = pe1.PUNCHEVENTID) LEFT JOIN 
            DATASOURCE AS ds1 ON pe1.DATASOURCEID = ds1.DATASOURCEID) LEFT JOIN 
                CLIENTCONTEXT AS cc1 ON ds1.CLIENTCONTEXTID = cc1.CLIENTCONTEXTID
    INNER JOIN PERSON p ON ti.EMPLOYEEID = p.PERSONID
    INNER JOIN LABORACCT la1 ON la1.laboracctid = ti.laboracctid
WHERE DATEDIFF(d,ti.EVENTDTM,GetDate()) <7
AND ti.TmShtItemTypeID = 40 
AND (isnull(cc.CLNT,'''') + isnull(cc1.CLNT,''''))<> '''') X
PIVOT
(
    SUM(SPAN) 
    FOR PunchDate in (' + @cols + ')
    ) p'

execute @query

【讨论】:

  • 太棒了,不敢相信我错过了。谢谢
  • @user2551567 很容易错过。捕获这些错误的一种方法是print @query,然后将结果粘贴到 SSMS 中,您会在处理动态 SQL 时发现问题
猜你喜欢
  • 2014-10-16
  • 2014-07-26
  • 2013-02-09
  • 2018-11-22
  • 1970-01-01
  • 2015-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多