我如何使用pivot来获得更多列。

时间:2015-08-20 09:29:00

标签: sql sql-server-2008

我有桌子LEAVTYPE: -

      LM_ID EMPCODE CCODE   FINYEAR  LVTYPE WEF                 OPN_BAL ENTITLE ELIGIBLE    AVAILED
       1    180480  IBTEH   2015-2016   CL  2015-07-31 00:00:00 4.50    0   4.50    1.50
       3    180480  IBTEH   2015-2016   LE  2015-07-31 00:00:00 35.50   0   35.50   0.00
       4    180480  IBTEH   2015-2016   PL  2015-07-31 00:00:00 6.00    1   7.00    0.00
       8    180541  IBTEH   2015-2016   LE  2015-07-31 00:00:00 33.50   0   33.50   0.50
       9    180541  IBTEH   2015-2016   PL  2015-07-31 00:00:00 1.50    1   2.50    1.50
      11    180546  IBTEH   2015-2016   CL  2015-07-31 00:00:00 8.00    0   8.00    1.00
      13    180546  IBTEH   2015-2016   LE  2015-07-31 00:00:00 32.00   0   32.00   0.00
      14    180546  IBTEH   2015-2016   PL  2015-07-31 00:00:00 6.00    1   7.00    0.00
      15    180546  IBTEH   2015-2016   CO  2015-07-31 00:00:00 1.00    0   1.00    1.00

现在我想表结构如: -

LM_ID  EMPCODE CCODE  FINYEAR     WEF                CL_OPN_BAL     CL_ENTITLE     CL_ELIGIBLE   CL_AVAILED    LE_OPN_BAL     LE_ENTITLE     LE_ELIGIBLE   LE_AVAILED    PL_OPN_BAL     PL_ENTITLE     PL_ELIGIBLE   PL_AVAILED 

1      180480  IBTEH 2015-2016  2015-07-31 00:00:00  4.50            0              4.50          1.50          35.50          0              35.50          0.00          6.00           1            7.00             0.00

我怎样才能为每组EMPCOPDE得到这个。

2 个答案:

答案 0 :(得分:1)

这会奏效。我们将根据LVTYPE从小组中收集其他统计数据。

WITH CTE
AS
(
SELECT LM_ID, EMPCODE, CCODE, FINYEAR, WEF, 
        CASE WHEN LVTYPE ='CL' THEN (OPN_BAL) END AS CL_OPN_BAL, 
        CASE WHEN LVTYPE ='CL' THEN (ENTITLE) END AS CL_ENTITLE, 
        CASE WHEN LVTYPE ='CL' THEN (ELIGIBLE) END AS CL_ELIGIBLE,
        CASE WHEN LVTYPE ='CL' THEN (AVAILED) END AS CL_AVAILED ,
        CASE WHEN LVTYPE ='LE' THEN (OPN_BAL) END AS LE_OPN_BAL,
        CASE WHEN LVTYPE ='LE' THEN (ENTITLE) END AS LE_ENTITLE,
        CASE WHEN LVTYPE ='LE' THEN (ELIGIBLE) END AS LE_ELIGIBLE,
        CASE WHEN LVTYPE ='LE' THEN (AVAILED) END AS LE_AVAILED, 
        CASE WHEN LVTYPE ='PL' THEN (OPN_BAL) END AS PL_OPN_BAL, 
        CASE WHEN LVTYPE ='PL' THEN (ENTITLE) END AS PL_ENTITLE, 
        CASE WHEN LVTYPE ='PL' THEN (ELIGIBLE) END AS PL_ELIGIBLE,
        CASE WHEN LVTYPE ='PL' THEN (AVAILED) END AS PL_AVAILED,             
        ROW_NUMBER() OVER(PARTITION BY EMPCOPDE ORDER BY EMPCOPDE) as indx
    FROM  LEAVTYPE

)

SELECT LM_ID, EMPCODE, CCODE, FINYEAR, WEF, CL_OPN_BAL, CL_ENTITLE, CL_ELIGIBLE,CL_AVAILED ,LE_OPN_BAL,LE_ENTITLE, LE_ELIGIBLE, LE_AVAILED, PL_OPN_BAL, PL_ENTITLE, PL_ELIGIBLE, PL_AVAILED
FROM CTE 
WHERE indx=1

组中有许多记录具有不同的indx值。 index = 1将显示每组中的一条记录。

答案 1 :(得分:0)

首先,您可以使用CROSS APPLYOUTER APPLY来获取行的列,以便将行值与列名组合起来

SELECT DISTINCT LM_ID,EMPCODE, CCODE, FINYEAR, WEF,
LVTYPE+'_'+COLNAME COLNAME,VALS
INTO NEWTBL
FROM TEMPTBL 
OUTER APPLY(VALUES (OPN_BAL,'OPN_BAL'),(ENTITLE,'ENTITLE'),(ELIGIBLE,'ELIGIBLE'),(AVAILED,'AVAILED'))
COLUMNNAMES(VALS,COLNAME) 

现在我已将其插入临时表NEWTBL,以便重复使用PIVOT列,以及动态PIVOT中的易读性。

这里我声明一个变量来选择用于旋转的列名。

DECLARE @cols NVARCHAR (MAX)

SELECT @cols = COALESCE (@cols + ',[' + COLNAME + ']', '[' + COLNAME + ']')
               FROM (SELECT DISTINCT COLNAME FROM NEWTBL) PV 
               ORDER BY COLNAME

现在您应该在动态查询中执行它,因为列名称本质上是动态的。

DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT * FROM 
             (
                 SELECT DISTINCT LM_ID,EMPCODE, CCODE, FINYEAR, WEF, COLNAME, VALS 
                 FROM NEWTBL
             ) x
             PIVOT 
             (
                 MIN(VALS)
                 FOR COLNAME IN (' + @cols + ')
            ) p
            '     
EXEC SP_EXECUTESQL @query

以下是工作版

<强> SQL FIDDLE

编辑:

为什么我的上述答案会重复EMPCODE,因为我根据您的预期结果添加了LM_ID。在这种情况下,它也会根据那个分组。只是不在结果中加入LM_ID,每个EMPCODE都会得到唯一的行。

Click here 查看结果