我在遗留系统中有以下SQL语句,我正在重构。对于这个问题,它是一个简略的视图,暂时只返回count(*)。
SELECT COUNT(*)
FROM Table1
INNER JOIN Table2
INNER JOIN Table3 ON Table2.Key = Table3.Key AND Table2.Key2 = Table3.Key2
ON Table1.DifferentKey = Table3.DifferentKey
它生成了大量的记录并杀死了系统,但有人可以解释一下语法吗?这可以用其他任何方式表达吗?
编辑:
建议重新格式化
SELECT COUNT(*)
FROM Table1
INNER JOIN Table3
ON Table1.DifferentKey = Table3.DifferentKey
INNER JOIN Table2
ON Table2.Key = Table3.Key AND Table2.Key2 = Table3.Key2
答案 0 :(得分:18)
为了便于阅读,我重新构建了查询...从表观最高级别为Table1开始,然后与Table3绑定,然后table3与table2绑定。如果你遵循关系链,就会更容易理解。
现在,回答你的问题。作为笛卡儿积的结果,你得到了很大的数量。对于Table1中与Table3匹配的每条记录,您将拥有X * Y.然后,对于table3和Table2之间的每个匹配将产生相同的影响... Y * Z ...因此,您在表1中只有一个可能的ID的结果可以有X * Y * Z记录。
这是基于不知道表格的规范化或内容如何...如果密钥是PRIMARY密钥而不是..
Ex:
Table 1
DiffKey Other Val
1 X
1 Y
1 Z
Table 3
DiffKey Key Key2 Tbl3 Other
1 2 6 V
1 2 6 X
1 2 6 Y
1 2 6 Z
Table 2
Key Key2 Other Val
2 6 a
2 6 b
2 6 c
2 6 d
2 6 e
因此,表1加入表3将导致(在此场景中)有12条记录(每条记录在1中加入,每条记录在3中)。然后,表2中每个匹配记录的所有次数(5条记录)...将返回总计60(3 tbl1 * 4 tbl3 * 5 tbl2)计数。
所以,现在,根据你的1000条记录进行扩展,你会看到一个混乱的结构如何扼杀一头牛(可以这么说)并杀死性能。
SELECT
COUNT(*)
FROM
Table1
INNER JOIN Table3
ON Table1.DifferentKey = Table3.DifferentKey
INNER JOIN Table2
ON Table3.Key =Table2.Key
AND Table3.Key2 = Table2.Key2
答案 1 :(得分:13)
由于您已经收到有关查询的帮助,我会捅你的语法问题:
第一个查询使用一些鲜为人知的ANSI SQL语法,允许您在join
和on
子句之间嵌套连接。这允许你对连接进行范围/分层,并且可能会打开许多其他邪恶的,神秘的东西。
现在,虽然嵌套连接不能在连接层次结构中引用比其直接父级更高的连接,但是在它之上或在其分支之外的连接可以引用它...这正是这个丑陋的小家伙正在做:
select
count(*)
from Table1 as t1
join Table2 as t2
join Table3 as t3
on t2.Key = t3.Key -- join #1
and t2.Key2 = t3.Key2
on t1.DifferentKey = t3.DifferentKey -- join #2
这看起来有点令人困惑,因为连接#2将t1连接到t2而没有专门引用t2 ...但是,它通过t3间接引用t2,而t3连接到连接#1中的t2。虽然这可能有用,但您可能会发现以下内容更多(视觉上)线性且吸引人:
select
count(*)
from Table1 as t1
join Table3 as t3
join Table2 as t2
on t2.Key = t3.Key -- join #1
and t2.Key2 = t3.Key2
on t1.DifferentKey = t3.DifferentKey -- join #2
就我个人而言,我发现以这种方式嵌套可以通过概述关系层次结构的每一层来保持我的陈述整洁。作为旁注,您不需要指定 inner 。 join 隐式内部,除非另有明确标记。