1
DECLARE @DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE @ColumnName AS NVARCHAR(MAX)

--Get distinct values of the PIVOT Column 
SELECT @ColumnName= ISNULL(@ColumnName + ',','') 
       + QUOTENAME(ACT_DESC)
FROM (SELECT DISTINCT ACT_DESC FROM tpc) AS desc

--Prepare the PIVOT query using the dynamic 
SET @DynamicPivotQuery = 
  N'SELECT MDCODE, ' + @ColumnName + '
    FROM tpc
    PIVOT(MAX(ACTUAL_DATE) 
          FOR tpcIN (' + @ColumnName + ')) AS PVTTable'
--Execute the Dynamic Pivot Query
EXEC sp_executesql @DynamicPivotQuery

此查询显示:

MDCODE | sample1 | sample2
--------------------------
123    | 1/2014  | 
123    |         | 2/2014
123    |         | 3/2014

我想要的是这样的:

MDCODE | sample1 | sample2
--------------------------
123    | 1/2014  | 2/2014,3/2014

有谁知道如何连接列数据?有小费吗?

这是我获取数据的表:

   mdcode | act_desc | actual_date
   --------------------------
   1234   | sample1  | 1/2014
   1234   | sample2  | 2/2014
   1234   | sample2  | 3/2014

实际日期是日期时间

4

2 回答 2

2

在 SQL Server 中,逗号分隔输出的类型是通过“for xml path”实现的,但通常也与 stuff() 相关联

可以选择通过“交叉应用”,尽管不必这样做。

我会这样处理它。现在不要使用pivot,只需通过 distinct 或 group by 减少 MDCODE 和 ACT_DESC,然后使用 cross apply 连接“日期”字符串。如果它们确实是日期,那么您需要将它们转换为 varchar,例如 convert(varchar,actual_date,112)

| MDCODE | ACT_DESC |  ACTUAL_DATES |
|--------|----------|---------------|
|   1234 |  sample1 |        1/2014 |
|   1234 |  sample2 | 2/2014,3/2014 |

由。。。生产:

SELECT
      d.mdcode
    , d.act_desc
    , ca1.actual_dates
FROM (
            SELECT DISTINCT
                  [mdcode]
                , [act_desc]
            FROM Table1
      ) d
      CROSS APPLY (
                  SELECT
                        STUFF((
                              SELECT
                                    ',' + a.actual_date
                              FROM table1 a
                              WHERE a.mdcode = d.mdcode
                                  AND a.act_desc = d.act_desc --<< change here
                              ORDER BY a.actual_date
                              FOR xml PATH ('')
                        )
                        , 1, 1, '')
            ) AS ca1 (actual_dates)
;

顺便说一句,STUFF() 用于从连接中删除第一个逗号,这是它的唯一作用。CROSS APPLY 可以说比在 select 子句中使用相关子查询更好,因为它是在该子句之前作为 from 子句的一部分执行的。正如我之前所说,它是可选的,但我更喜欢它。

请参阅:http ://sqlfiddle.com/#!3/a24ba /4 并查看这些示例

于 2014-08-14T05:41:19.630 回答
1

我会完全跳过 PIVOT,只使用 FOR XML_PATH,如下所示:

DECLARE @DynamicPivotQuery AS NVARCHAR(MAX)

--Get distinct values of the PIVOT Column 
SELECT @DynamicPivotQuery= ISNULL(@DynamicPivotQuery + ',','select mdcode,') 
       + 'stuff((select '',''+actual_date from tpc where mdcode=t.mdcode and act_desc = ''' + ACT_DESC + ''' for xml path(''''),type).value(''.'',''varchar(max)''),1,1,'''') '
       + QUOTENAME(ACT_DESC)
FROM (SELECT DISTINCT ACT_DESC FROM tpc) AS des

select @DynamicPivotQuery = @DynamicPivotQuery + 'from tpc t group by mdcode'
EXEC sp_executesql @DynamicPivotQuery

动态查询生成如下查询:

select mdcode,
        stuff(
              (
                select ','+actual_date
                from tpc where mdcode=t.mdcode and act_desc = 'sample1'
                for xml path(''),type
              ).value('.','varchar(max)')
              ,1,1,'') sample1,
        stuff(
              (
                select ','+actual_date
                from tpc where mdcode=t.mdcode and act_desc = 'sample2'
                for xml path(''),type
              ).value('.','varchar(max)')
              ,1,1,'') sample2
from tpc t
group by mdcode;

SQL Fiddle演示了静态查询和动态查询

于 2014-08-14T06:06:36.323 回答