在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倍,但是,在实际运行查询时,基本内部连接的速度是嵌套查询的两倍。最少的服务器硬件。

我们正在使用哪个数据库,并且看到什么时间?我在想,如果我们看到性能不佳,那么可能是索引问题。