枚举和关联表以避免笛卡尔连接

问题描述 投票:0回答:1

我有一组表,我想从中提取所有数据,其中的列列出了辅助表的内容。

例如:

状态

代码 名字
增强现实 阿肯色州
CT 康涅狄格州
明尼苏达 缅因州

参议员

代码 名字
增强现实 凯蒂布里特
增强现实 汤米·图伯维尔
CT 克里斯墨菲
CT 理查德·布卢门撒尔
明尼苏达 安格斯王
明尼苏达 苏珊·柯林斯

代表们

代码 名字
增强现实 布鲁斯·韦斯特曼
增强现实 法国山
增强现实 里克·克劳福德
增强现实 史蒂夫·沃马克
CT 贾哈纳·海耶斯
CT 吉姆·希姆斯
CT 乔·考特尼
CT 约翰·B·拉尔森
CT 罗莎·德劳罗
明尼苏达 切莉·平格里
明尼苏达 贾里德·戈尔登

我想要一个州专栏、参议员专栏和代表专栏,如下所示:

状态 参议员 代表
阿肯色州 凯蒂布里特 布鲁斯·韦斯特曼
阿肯色州 汤米·图伯维尔 法国山
阿肯色州 里克·克劳福德
阿肯色州 史蒂夫·沃马克
康涅狄格州 克里斯墨菲 贾哈纳·海耶斯
康涅狄格州 理查德·布卢门撒尔 吉姆·希姆斯
康涅狄格州 乔·考特尼
康涅狄格州 约翰·B·拉尔森
康涅狄格州 罗莎·德劳罗
缅因州 安格斯王 切莉·平格里
缅因州 苏珊·柯林斯 贾里德·戈尔登

到目前为止我想到的是:

select states.name state, sens.name senator, reps.name representative
from states
left join
( select state_code, name
  , row_number() over (partition by state_code order by name) rn
  from representatives
) reps on reps.state_code = states.code 
full outer join 
( select state_code, name
  , row_number() over (partition by state_code order by name) rn
  from senators
) sens on sens.state_code = states.code and sens.rn = reps.rn

(抱歉,我之前发布了一个不正确的版本,其中两个连接方式错误)

这可行,但它依赖于我首先加入众议员,然后加入参议员,因为总是有更多的代表。如果某个州的代表列表未填充,或者填充的行数少于参议员的行数,则它会崩溃。

我的现实世界要求不是州、参议员和代表,但这是一个易于解释的类比。第二个和第三个表实际上都在一个表中,我需要对其进行十几个或更多的连接,而不仅仅是两个。

有什么想法可以让这个更通用来处理 from-join 子句中的第二个表的行数少于第三个表或零的情况吗?

sql window-functions cartesian-product
1个回答
0
投票

您走在正确的道路上。首先对基表进行编号,然后将它们完全外部连接在一起,然后加入状态名称。

Select st.name as state, s.name as senator, r.name as representative
From (
    (Select *
        , row_number() Over (Partition by code) as nbr
     From senators) s
  Full Outer Join
    (Select *
        , row_number() Over (Partition by code) as normal
     From representatives) r
  On s.code=r.code and s.nbr=r.nbr
) Inner Join states st On Coalesce(r.code,s.code)=st.code
© www.soinside.com 2019 - 2024. All rights reserved.