我有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中有一个颜色的记录,那么它将是相应颜色列的真值。
任何帮助表示感谢。
答案 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
编辑:我错过了每个用户一行的支点。但是会议时间。回来一点。