在SQL中使用DISTINCT内部联接
时间:2020-03-06 15:00:57 来源:igfitidea点击:
我有三个表,A,B,C,其中A对B的个数很多,而B对C的个数很多。
我的表是这样的:A [id,valueA,lookupB],B [id,valueB,lookupC],C [id,valueC]。我已经编写了带有两个嵌套SELECT的查询,但是我想知道是否可以通过DISTINCT进行INNER JOIN。
SELECT valueC FROM C INNER JOIN ( SELECT DISTINCT lookupC FROM B INNER JOIN ( SELECT DISTINCT lookupB FROM A ) A2 ON B.id = A2.lookupB ) B2 ON C.id = B2.lookupC
编辑:
这些表相当大,A是50万行,B是1万行,C是100行,因此,如果我进行基本的内部联接并最终使用DISTINCT,则会有很多不必要的信息,例如:
SELECT DISTINCT valueC FROM C INNER JOIN B on C.id = B.lookupB INNER JOIN A on B.id = A.lookupB
这非常非常慢(幅度比我上面做的嵌套SELECT慢几倍)。
解决方案
你是这个意思吗?
SELECT DISTINCT C.valueC FROM C INNER JOIN B ON C.id = B.lookupC INNER JOIN A ON B.id = A.lookupB
我相信1:m关系应该已经隐式创建了DISTINCT JOIN。
但是,如果目标只是每个A中的C,那么对最外面的查询使用DISTINCT可能会更容易。
SELECT DISTINCT a.valueA, c.valueC FROM C INNER JOIN B ON B.lookupC = C.id INNER JOIN A ON A.lookupB = B.id ORDER BY a.valueA, c.valueC
SELECT DISTINCT C.valueC FROM C LEFT JOIN B ON C.id = B.lookupC LEFT JOIN A ON B.id = A.lookupB WHERE C.id IS NOT NULL
我看不出为什么要限制A和B的结果集的充分理由,因为我们要拥有的是A引用的所有C的列表。我在C.valueC上做了与众不同的原因,因为我猜到了我们想要C的唯一列表。
编辑:我同意你的论点。即使解决方案看起来有点嵌套,它似乎也是使用我们对数据的了解并减少结果集的最佳,最快的方法。
没有可以使用的独特的join构造,因此只需保留已有的内容即可:)
我使用下表对MS SQL 2005进行了测试:A 400K行,B 26K行和C 450行。
估计的查询计划表明,基本内部连接的速度将比嵌套子查询慢3倍,但是,在实际运行查询时,基本内部连接的速度是嵌套查询的两倍。最少的服务器硬件。
我们正在使用哪个数据库,并且看到什么时间?我在想,如果我们看到性能不佳,那么可能是索引问题。