SQL Server展平数据

时间:2015-09-15 15:27:17

标签: sql sql-server pivot-table crosstab

我有3张桌子:

tUsers
  -uid

tColors
  -colorid
  -colorname

tColors_User_Detail
  -uid_fk
  -colorid_fk

用户选择他们喜欢的颜色,只选择他们喜欢的颜色。这会在tColors_User_Detail中创建记录。我需要将其展平,以便每个用户都有一条记录,其颜色来自tColors作为列名,并且每个颜色的行中都有一个True / False值,具体取决于它们是否在tColors_User_Detail中有记录。如果用户没有在tColors_User_Detail中选择颜色,则在特定颜色列中它将是一个False值。并且,如果它们在tColors_User_Detail中有一个颜色的记录,那么它将是相应颜色列的真值。

任何帮助表示感谢。

2 个答案:

答案 0 :(得分:2)

这是一个基本的PIVOT示例,其中有一个COALESCE来显示' false'如果没有值可用。这假设您必须硬编码列名称的颜色名称。

DECLARE @tUsers TABLE ([uid] INT)
DECLARE @tColors TABLE ([colorid] INT, [colorname] VARCHAR(50))
DECLARE @tColors_User_Detail TABLE ([uid_fk] INT, [colorid_fk] INT)
INSERT @tUsers VALUES (1),(2)
INSERT @tColors VALUES (1,'Blue'),(2,'Red'),(3,'Green')
INSERT @tColors_User_Detail VALUES (1,1),(1,2),(1,3),(2,1)

SELECT
    uid,
    COALESCE([Red], 'False') AS [Red],
    COALESCE([Blue], 'False') AS [Blue],
    COALESCE([Green], 'False') AS [Green]
FROM @tUsers U
    LEFT OUTER JOIN @tColors_User_Detail CUD
        ON CUD.uid_fk = U.uid
    LEFT OUTER JOIN @tColors C
        ON C.colorid = CUD.colorid_fk
    PIVOT (MAX(colorname) FOR colorname IN (
        [Red],
        [Blue],
        [Green]
    )) PVT

如果你想让列从颜色变为动态,你必须使用动态sql。

DECLARE @Sql VARCHAR(1000) =
    'SELECT uid'
    + (SELECT ', CASE WHEN [' + [colorname] + '] IS NOT NULL THEN ''True'' ELSE ''False'' END AS [' + [colorname] + ']' AS [text()] FROM tColors FOR XML PATH(''))
    + ' FROM tUsers  U
            LEFT OUTER JOIN tColors_User_Detail CUD
                ON CUD.uid_fk = U.uid
            LEFT OUTER JOIN tColors C
                ON C.colorid = CUD.colorid_fk
            PIVOT (MAX(colorname) FOR colorname IN ('
    + SUBSTRING((SELECT ',[' + [colorname] + ']' AS [text()] FROM tColors FOR XML PATH('')), 2, 1000)
    + ')) PVT'
EXEC (@Sql)

答案 1 :(得分:1)

什么样的SQL?

以下内容: http://sqlfiddle.com/#!6/ec4e2

SELECT U.uid
  , C.colorid
  , C.colorname
  , ( CASE WHEN cud.uid_fk IS NOT NULL THEN 'True' ELSE 'False' END ) AS ColorChosen
FROM tUsers U
FULL OUTER JOIN tColors C ON 1=1
LEFT OUTER JOIN tColors_User_Detail cud ON 
  U.uid = cud.uid_fk
  AND C.colorid = cud.colorID_FK 

编辑:我错过了每个用户一行的支点。但是会议时间。回来一点。