在数据透视视图中连接列

时间:2014-08-14 05:12:12

标签: sql sql-server pivot concat sql-server-group-concat

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

actual_date是日期时间

2 个答案:

答案 0 :(得分:2)

在SQL Server中,逗号分隔输出的类型使用"实现xml路径",但通常也与stuff()

相关联

可选择通过"交叉申请"虽然不必这样做。

我会像这样接近它。现在不要使用pivot,只需减少MDCODE& ACT_DESC由distinct或group by组成,然后使用交叉应用连接" date"的字符串。如果它们确实是日期,那么您需要将它们转换为varchar,例如转换(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 &安培;另见these samples

答案 1 :(得分: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演示静态查询和动态查询