展平单个表格

时间:2012-07-03 14:58:20

标签: sql

我正在寻找一个非常基本的扁平化。我在数据库中有一个表,它为不同行中的员工提供每个字段。

EX 
  EMPLOYEE         GROUP_NAME
   81               BNEEO55
   81               BNELLIG
   81               LPKAPE
   81               HRFT
   90               BNRETINV
  ....

我想创建一个将数据报告为:

的视图
EMPLOYEE     Group1      Group2        Group3         Group4         Group5
81           BNEEO55     BNELLIG       LPKAPE         HRFT           NULL
90           NULL        NULL          NULL           NULL           BNRETINV

OR

EMPLOYEE    BNEEO55     BNELLIG       LPKAPE         HRFT           BNRETINV
81          YES         YES           YES            YES            NO
90          NO          NO            NO             NO             YES 

1 个答案:

答案 0 :(得分:4)

您需要PIVOT数据,如果您使用的是SQL-Server 2008或更高版本,则可以使用PIVOT功能:

CREATE TABLE #T (Employee INT, Group_name VARCHAR(50))
INSERT #T VALUES (81, 'BNEEO55'), (81, 'BNELLIG'), (81, 'LPKAPE'), (81, 'HRFT'), (90, 'BNRETINV')

SELECT  Employee, 
        COALESCE([BNEEO55],'No') AS [BNEEO55],
        COALESCE([BNELLIG],'No') AS [BNELLIG],
        COALESCE([BNRETINV],'No') AS [BNRETINV],
        COALESCE([HRFT],'No') AS [HRFT],
        COALESCE([LPKAPE],'No') AS [LPKAPE]
FROM    (   SELECT  *, 'Yes' [Data]
            FROM    #T
        ) d
        PIVOT
        (   MAX(Data)
            FOR Group_Name IN ([BNEEO55], [BNELLIG], [BNRETINV], [HRFT], [LPKAPE])
        ) pvt

但听起来你需要在数据发生变化时动态地进行动态操作。以下内容可行:

DECLARE @SQL NVARCHAR(MAX) = '',
        @Cols NVARCHAR(MAX) = ''

SELECT  @SQL = @SQL + ',' + QUOTENAME(Group_Name),
        @Cols = @Cols + ',COALESCE(' + QUOTENAME(Group_Name) + ',''No'') AS ' + QUOTENAME(Group_Name)
FROM    (   SELECT  DISTINCT Group_Name 
            FROM    #T
        ) T

SET @SQL = '
            SELECT  Employee, ' + STUFF(@Cols, 1, 1, '') + 
            'FROM   (   SELECT  *, ''Yes'' [Data]
                        FROM    #T
                    ) d
                    PIVOT
                    (   MAX(Data)
                        FOR Group_Name IN (' + STUFF(@SQL, 1, 1, '') + ')
                    ) pvt'

EXECUTE SP_EXECUTESQL @SQL

这构建了与第一个查询相同的查询,但意味着当添加新组名时,不必更改查询。


修改

创建并将其作为存储过程调用:

CREATE TABLE T (Employee INT, Group_name VARCHAR(50))
INSERT T VALUES (81, 'BNEEO55'), (81, 'BNELLIG'), (81, 'LPKAPE'), (81, 'HRFT'), (90, 'BNRETINV')
GO
CREATE PROCEDURE PivotT
AS

DECLARE @SQL NVARCHAR(MAX) = '',
        @Cols NVARCHAR(MAX) = ''

SELECT  @SQL = @SQL + ',' + QUOTENAME(Group_Name),
        @Cols = @Cols + ',COALESCE(' + QUOTENAME(Group_Name) + ',''No'') AS ' + QUOTENAME(Group_Name)
FROM    (   SELECT  DISTINCT Group_Name 
            FROM    T
        ) T

SET @SQL = '
            SELECT  Employee, ' + STUFF(@Cols, 1, 1, '') + 
            'FROM   (   SELECT  *, ''Yes'' [Data]
                        FROM    T
                    ) d
                    PIVOT
                    (   MAX(Data)
                        FOR Group_Name IN (' + STUFF(@SQL, 1, 1, '') + ')
                    ) pvt'

EXECUTE SP_EXECUTESQL @SQL
GO
EXECUTE PivotT