可以扩展 x 数量的选项和值组合的查询
Posted
技术标签:
【中文标题】可以扩展 x 数量的选项和值组合的查询【英文标题】:Query that can scale for x amount of options & values combinations 【发布时间】:2018-02-02 06:21:23 【问题描述】:试图返回每辆汽车的每个选项值组合的结果,但在理解如何做时遇到了一些麻烦。
这是所涉及的表的结构和所需的结果。我在网上找到的唯一一件事是关于使用交叉连接,但在这种情况下,选项维度的数量是未知的,所以这不会像我预期的那样工作。
请参阅下面所需的结构/结果:
我熟悉使用 STUFF() FOR XML,因此将它们组合起来不是问题,但问题是找到它将正确返回值以进行定义的查询。
【问题讨论】:
您的数据让我有些困惑。目前尚不清楚生成输出的逻辑是什么。 图片已更新,更有意义 您提到特征的数量(例如颜色、年份)是任意的。这意味着您需要每个品牌的特征的 n 维笛卡尔积。这使得这个问题成为this 的欺骗和(以更现代的风格)我即将投票关闭的问题... Cross join N sets of rows in same table的可能重复 问题是,该链接的答案表明这些名称是已知的。在这种情况下,它们可以是动态的/未知的。 【参考方案1】:检查这个查询
with myTable as (
select
*
from
(values
('BMW','COLOR','Black')
,('BMW','COLOR','Red')
,('BMW','COLOR','Blue')
,('BMW','YEAR','2010')
,('BMW','YEAR','2011')
,('Ferrari','COLOR','Yellow')
,('Ferrari','COLOR','White')
,('Ferrari','YEAR','2012')
,('Ferrari','YEAR','2013')
) t(car, name, value)
)
select
a.car, a.value + ' ' + b.value
from
myTable a
join myTable b on a.car = b.car and a.name <> b.name
where
a.name = 'COLOR'
and b.name = 'YEAR'
【讨论】:
维数未知怎么办?所以查询应该返回任意数量的维度.. 颜色、年份、英里、最高速度等 - 未知.. 如果不知道dimesions 的数量,您将不知道需要多少表连接。所以,我认为在这种情况下你需要动态 SQL 对,但是在这种情况下有没有办法避免动态sql? 目前我认为这是不可能的。如果我能找到这样的方法,我会告诉你的【参考方案2】:请试试这个。
Declare @CAR AS TABLE
(
car varchar(100),
name varchar(100),
value varchar(100)
)
insert into @CAR
values
('BMW','COLOR','Black')
,('BMW','COLOR','Red')
,('BMW','COLOR','Blue')
,('BMW','YEAR','2010')
,('BMW','YEAR','2011')
,('Ferrari','COLOR','Yellow')
,('Ferrari','COLOR','White')
,('Ferrari','YEAR','2012')
,('Ferrari','YEAR','2013')
Select b.car,a.value + ' ' + b.value as value from @CAR b RIGHT OUTER JOIN (
Select car,name,value as value from @CAR where name='COLOR') as a on a.car = b.car and b.name='YEAR'
【讨论】:
【参考方案3】:试试下面的查询,这里使用了CTE
。我只是使用前 3 或 4 个 CTE 来生成主数据,您可以根据您的表结构更改它。
WITH AUTOMOBILES
AS (
SELECT 1 ID,'BMW M3' Name
UNION
SELECT 2,'Ferrari F 430'
), OPTIONS
AS (
SELECT 1 ID,'Color' Name
UNION
SELECT 2,'Year'
UNION
SELECT 3,'Top Speed'
),AM_VALUES
AS (
SELECT 1 ID,1 AutomobileID,1 OptionID,'Black' Value
union
select 2,1,1,'Red'
union
select 3,1,1,'Blue'
union
select 4,1,2,'2010'
union
select 5,1,2,'2011'
union
select 6,2,1,'Yellow'
union
select 7,2,1,'white'
union
select 8,2,2,'2012'
union
select 9,2,2,'2013'
union
select 10,2,3,'Sp210'
union
select 11,2,3,'Sp190'
),INPUT_TABLE
AS (
SELECT V.ID,V.AutomobileID,A.Name Car,V.OptionID,O.Name, V.Value
,DENSE_RANK() OVER(PARTITION BY V.AutomobileID ORDER BY V.OptionID ) AS OptionRowNo
FROM AM_VALUES AS V
INNER JOIN AUTOMOBILES AS A ON A.ID = V.AutomobileID
INNER JOIN OPTIONS AS O ON O.ID = V.OptionID
),VTREE
AS (
SELECT DISTINCT AutomobileID,ID AS Node,NULL AS Parent,OptionRowNo,CAST(Value AS nvarchar) AS Value,1 RowNo
FROM INPUT_TABLE
WHERE OptionRowNo = 1
UNION ALL
SELECT V.AutomobileID,I.ID,V.Node,I.OptionRowNo,CAST(V.Value+' '+I.Value AS nvarchar),RowNo=RowNo+1
FROM VTREE AS V
INNER JOIN INPUT_TABLE AS I ON I.AutomobileID = V.AutomobileID
AND I.OptionRowNo > V.OptionRowNo
)
SELECT AutomobileID,Value
FROM VTREE AS V
WHERE RowNo = ( SELECT TOP 1 COUNT(DISTINCT I1.OptionID)
FROM INPUT_TABLE AS I1
WHERE I1.AutomobileID = V.AutomobileID
GROUP BY I1.AutomobileID)
ORDER BY AutomobileID,Value
输出:-
AutomobileID Value
1 Black 2010
1 Black 2011
1 Blue 2010
1 Blue 2011
1 Red 2010
1 Red 2011
2 white 2012 Sp190
2 white 2012 Sp210
2 white 2013 Sp190
2 white 2013 Sp210
2 Yellow 2012 Sp190
2 Yellow 2012 Sp210
2 Yellow 2013 Sp190
2 Yellow 2013 Sp210
【讨论】:
以上是关于可以扩展 x 数量的选项和值组合的查询的主要内容,如果未能解决你的问题,请参考以下文章
在一个 Power Query 中合并多个工作簿中的相同选项卡