将一对多字符串结果作为组合查询中的列
Posted
技术标签:
【中文标题】将一对多字符串结果作为组合查询中的列【英文标题】:Getting one-to-many string results as columns in a combined query 【发布时间】:2021-02-22 22:25:36 【问题描述】:使用 SQL Server。这似乎有点像带有 ROW_NUMBER 的 Pivot,但我在学习曲线上遇到了很多麻烦,无法弄清楚所有可以在我的 2 张桌子上工作的部分。
表 A 中每个项目都有一行(按 ID)。我的结果中需要此表中的一些列值。
表 B 的每个项目都有多行,每行描述项目的不同配置设置值。每个配置设置都有一个名称和一个值。我想从表 B 中提取几个不同的设置名称,并在结果集中的列中显示匹配的设置值。
Table A
ID | Name
1001 | William
1002 | Patricia
Table B
ID | ItemID | Setting | Value
999 | 1001 | EyeColor | Blue
998 | 1001 | Nickname | Billy
997 | 1002 | Nickname | Trish
996 | 1002 | EyeColor | Green
Desired Result
ItemID | Name | EyeColor | Nickname
1001 | William | Blue | Billy
1002 | Patricia| Green | Trish
我目前正在做的事情是:
SELECT
A.ID,
A.Name,
'EyeColor' = (SELECT B.Value FROM B WHERE B.ItemID = A.ID AND B.Setting = 'EyeColor'),
'Nickname' = (SELECT B.Value FROM B WHERE B.ItemID = A.ID AND B.Setting = 'Nickname')
FROM TableA as A
WHERE (some criteria that filters on values in Table A)
但这似乎很笨拙,我有点想知道这是否不能很好地扩展到表 A 的结果集中包含 2000 个项目的结果集。
关于更好的方法的建议?
【问题讨论】:
可以肯定的是,这是最好的......没有捷径。 这很笨拙,因为这不是一个正确规范化的模式。您有一个 EAV 设计(搜索网络以获取更多信息) - 您现在可以更好地理解为什么“灵活性”会带来重大损失。 唯一的其他解决方案同样笨拙,可能会或可能不会更高效:加入表格并按 ID 分组,名称然后选择MIN(CASE WHEN B.Setting = 'EyeColor' THEN B.VALUE END)
【参考方案1】:
按项目 id 分组并加载 EyeColor 和 NickName 列中的数据
unpivot 相当于 python 融化
declare @tmp as table(ItemID int, EyeColor varchar(20), NickName varchar(20))
insert into @tmp(ItemID, EyeColor,NickName)
Values(1001 , 'Blue','Billy')
,( 1002 ,'Green' , 'Trish')
select * from @tmp
select ItemID,Variables
from
(select ItemID,EyeColor,NickName from @tmp) source
UNPIVOT
(Variables for Setting in (EyeColor,NickName)) as unpvt
ItemID EyeColor NickName
1001 Blue Billy
1002 Green Trish
ItemID Variables
1001 Blue
1001 Billy
1002 Green
1002 Trish
declare @tmp2 as table(ID int, ItemID int, Setting varchar(20), Data varchar(20))
insert into @tmp2(ID,ItemID, Setting, Data)
Values(1,1001, 'EyeColor','Blue')
,(2,1001,'NickName','Billy')
,(3,1002,'EyeColor','Green')
,(4,1002,'NickName','Trish')
select ItemID, Max(Case When Setting='EyeColor' then Data End) EyeColor,
Max(Case When Setting='NickName' then Data End) NickName
from @tmp2
group by ItemID
ItemID EyeColor NickName
1001 Blue Billy
1002 Green Trish
【讨论】:
您能否推荐一个参考资料来解释当您不想聚合时如何使用 PIVOT? MS 的语法专门讨论了聚合(例如 COUNT、MIN、MAX),但据我所知,我并没有尝试聚合任何东西。 只有当您有要聚合的列 docs.microsoft.com/en-us/sql/t-sql/queries/… 时,Pivot 才有效 red-gate.com/simple-talk/sql/t-sql-programming/… 您可以使用 case 何时对数据进行平方,但它是代码密集型的。最好以正方形形式加载数据以上是关于将一对多字符串结果作为组合查询中的列的主要内容,如果未能解决你的问题,请参考以下文章