SQL 不等式加入返回的笛卡尔积
Posted
技术标签:
【中文标题】SQL 不等式加入返回的笛卡尔积【英文标题】:SQL Inequality joins returning cartesian product 【发布时间】:2013-04-22 18:31:13 【问题描述】:我在获取连接条件以隔离唯一记录时遇到问题。我的查询返回笛卡尔积,我不知道如何让它停止。我的表格如下所示:
Table A
ID_1 Start End Name
137 1:00 2:00 Galia
137 2:00 3:00 Est
137 3:00 4:00 Omnia
137 4:00 5:00 Divisa
137 5:00 6:00 Partes
137 6:00 7:00 Tres
137 7:00 8:00 Quarum
137 8:00 9:00 Unam
137 9:00 10:00 Incolunt
Table B
ID_1Time_1 Time_2
137 3:10 3:57
我的查询是:
select A.*, B.Time_1, B.Time_2
from Table_A A
inner join
Table_B B
on
A.ID_1 = B.ID_1 and B.Time_1<=A.End and B.Time_2 >= A.Start
我得到的看起来像这样:
ID_1Start End Name Time_1 Time_2
137 1:00 2:00 Galia 3:10 3:57
137 2:00 3:00 Est 3:10 3:57
137 3:00 4:00 Omnia 3:10 3:57
137 4:00 5:00 Divisa 3:10 3:57
137 5:00 6:00 Partes 3:10 3:57
137 6:00 7:00 Tres 3:10 3:57
137 7:00 8:00 Quarum 3:10 3:57
137 8:00 9:00 Unam 3:10 3:57
137 9:00 10:00 Incolunt3:10 3:57
所以看起来它给出了两个表的笛卡尔积,考虑到每条记录都满足所有三个条件,这是有道理的。我想要的只是返回时间对应的记录,如下所示:
ID_1Start End Name Time_1 Time_2
137 3:00 4:00 Omnia 3:10 3:57
关于如何构建连接以实现此目标的任何建议?如果这有助于提供可用功能,我正在开发一个 Netezza 盒子。谢谢。
【问题讨论】:
这些时代的数据类型是什么?3:57 >= 9:00
的正确性如何?
@TomR 。 . .使用提供的数据,您的查询应该可以正常工作(即返回一行)。您确定包含正确的查询和示例数据吗?
这不是笛卡尔积。
这不是实际数据,这是我无法发布的专有公司数据。但是这个数据代表了这个问题。它是一个笛卡尔积,因为查询似乎正在做的是测试是否在表中的任何地方都满足不等式连接,然后返回 ID 匹配的任何记录,从而给出 ID 和名称的笛卡尔积。无论不等式是在连接中还是在 where 子句中,它都会返回多行。
【参考方案1】:
您希望满足以下条件:
A.Start <= B.Time_1 <= B.Time_2 <= A.End
假设列数据类型是一致的(即仅存储时间,而不是日期时间或时间戳),并且值是一致的(即,上述多重关系中的中心谓词已经有效)。这些条件可以用 SQL 重写为
B.Time_2 <= A.End AND B.Time_1 >= A.Start
而不是
B.Time_1 <= A.End and B.Time_2 >= A.Start
可以对应
B.Time_1 <= A.Start <= A.End <= B.Time_2
因此:
select A.*, B.Time_1, B.Time_2
from Table_A A
inner join
Table_B B
on
A.ID_1 = B.ID_1 and B.Time_1>=A.Start and B.Time_2 <= A.End
【讨论】:
谢谢你,我希望你不介意我用一些解释来扩展你的答案。以上是关于SQL 不等式加入返回的笛卡尔积的主要内容,如果未能解决你的问题,请参考以下文章
工作总结之因为笛卡尔积问题写SQL搞了半天[害](附笛卡尔积总结)