Sql 结合内连接和左连接 编辑

Sql 结合内连接和左连接 编辑,sql,Sql,我不是问如何编写好的查询,但这3个查询返回相同的结果 查询1 SELECT v1.id FROM ( SELECT DISTINCT t1.id FROM t1 LEFT JOIN t2 ON t1.id = t2.id WHERE t2.id IS NULL ) v1 INNER JOIN ( SELECT DISTINCT t3.id FROM t3 LEFT JOIN t4 ON t3.id = t4.id WHERE t4.id IS NU

我不是问如何编写好的查询,但这3个查询返回相同的结果

查询1

SELECT v1.id
FROM (
    SELECT DISTINCT t1.id
    FROM t1 LEFT JOIN t2 ON t1.id = t2.id
    WHERE t2.id IS NULL
) v1 INNER JOIN (
    SELECT DISTINCT t3.id
    FROM t3 LEFT JOIN t4 ON t3.id = t4.id
    WHERE t4.id IS NULL
) v2 ON v1.id = v2.id;
查询2

SELECT DISTINCT t1.id
FROM (t1 LEFT JOIN t2 ON t1.id = t2.id)
    INNER JOIN (t3 LEFT JOIN t4 ON t3.id = t4.id) ON t1.id = t3.id
WHERE t2.id IS NULL AND t4.id IS NULL;
查询3

SELECT DISTINCT t1.id
FROM t1 LEFT JOIN t2 ON t1.id = t2.id
    INNER JOIN t3 ON t1.id = t3.id LEFT JOIN t4 ON t3.id = t4.id
WHERE t2.id IS NULL AND t4.id IS NULL;
查询不是由程序员硬编码的,而是由用户输入动态生成的

例如,当用户在t1(但不在t2)和t3(但不在t4)中插入
find id
时,他的缩进是
Query 1
。但目前我的程序生成了
query3
,看起来还可以。我想知道这个查询在某些情况下有一个bug,所以应该像
query2
1
那样进行更改

用户输入(如上所示)只是一个例子,最终对我来说,将用户输入转换为JOIN语句是很困难的


高级版谢谢。

这是原始查询:

SELECT v1.id
FROM (SELECT DISTINCT t1.id
      FROM t1 LEFT JOIN t2 ON t1.id = t2.id
      WHERE t2.id IS NULL
     ) v1 INNER JOIN
     (SELECT DISTINCT t3.id
      FROM t3 LEFT JOIN t4 ON t3.id = t4.id
      WHERE t4.id IS NULL
     ) v2
     ON v1.id = v2.id;
如果我理解正确,您需要
id
s位于
t1
t3
中,但不在
t2
t4

我想把第二个问题表述为:

SELECT distinct t1.id
FROM t1 INNER JOIN
     t3
     on t1.id = t3.id LEFT JOIN
     t2
     on t1.id = t2.id LEFT JOIN
     t4
     on t1.id = t4.id
WHERE t2.id IS NULL AND t4.id IS NULL;

这是原始查询:

SELECT v1.id
FROM (SELECT DISTINCT t1.id
      FROM t1 LEFT JOIN t2 ON t1.id = t2.id
      WHERE t2.id IS NULL
     ) v1 INNER JOIN
     (SELECT DISTINCT t3.id
      FROM t3 LEFT JOIN t4 ON t3.id = t4.id
      WHERE t4.id IS NULL
     ) v2
     ON v1.id = v2.id;
如果我理解正确,您需要
id
s位于
t1
t3
中,但不在
t2
t4

我想把第二个问题表述为:

SELECT distinct t1.id
FROM t1 INNER JOIN
     t3
     on t1.id = t3.id LEFT JOIN
     t2
     on t1.id = t2.id LEFT JOIN
     t4
     on t1.id = t4.id
WHERE t2.id IS NULL AND t4.id IS NULL;

这是原始查询:

SELECT v1.id
FROM (SELECT DISTINCT t1.id
      FROM t1 LEFT JOIN t2 ON t1.id = t2.id
      WHERE t2.id IS NULL
     ) v1 INNER JOIN
     (SELECT DISTINCT t3.id
      FROM t3 LEFT JOIN t4 ON t3.id = t4.id
      WHERE t4.id IS NULL
     ) v2
     ON v1.id = v2.id;
如果我理解正确,您需要
id
s位于
t1
t3
中,但不在
t2
t4

我想把第二个问题表述为:

SELECT distinct t1.id
FROM t1 INNER JOIN
     t3
     on t1.id = t3.id LEFT JOIN
     t2
     on t1.id = t2.id LEFT JOIN
     t4
     on t1.id = t4.id
WHERE t2.id IS NULL AND t4.id IS NULL;

这是原始查询:

SELECT v1.id
FROM (SELECT DISTINCT t1.id
      FROM t1 LEFT JOIN t2 ON t1.id = t2.id
      WHERE t2.id IS NULL
     ) v1 INNER JOIN
     (SELECT DISTINCT t3.id
      FROM t3 LEFT JOIN t4 ON t3.id = t4.id
      WHERE t4.id IS NULL
     ) v2
     ON v1.id = v2.id;
如果我理解正确,您需要
id
s位于
t1
t3
中,但不在
t2
t4

我想把第二个问题表述为:

SELECT distinct t1.id
FROM t1 INNER JOIN
     t3
     on t1.id = t3.id LEFT JOIN
     t2
     on t1.id = t2.id LEFT JOIN
     t4
     on t1.id = t4.id
WHERE t2.id IS NULL AND t4.id IS NULL;

我将您最初的查询理解为要求“T1中的所有ID都在T1和T3中,但不在T2或T4中”。对吗?如果是,我的问题是:

SELECT DISTINCT t1.id
FROM t1
WHERE EXISTS (SELECT 1 FROM t3 WHERE t1.id = t3.id)
AND  NOT  EXISTS  (SELECT 1 FROM t2 WHERE t1.id = t2.id)
AND  NOT  EXISTS  (SELECT 1 FROM t4 WHERE t1.id = t4.id)

我将您最初的查询理解为要求“T1中的所有ID都在T1和T3中,但不在T2或T4中”。对吗?如果是,我的问题是:

SELECT DISTINCT t1.id
FROM t1
WHERE EXISTS (SELECT 1 FROM t3 WHERE t1.id = t3.id)
AND  NOT  EXISTS  (SELECT 1 FROM t2 WHERE t1.id = t2.id)
AND  NOT  EXISTS  (SELECT 1 FROM t4 WHERE t1.id = t4.id)

我将您最初的查询理解为要求“T1中的所有ID都在T1和T3中,但不在T2或T4中”。对吗?如果是,我的问题是:

SELECT DISTINCT t1.id
FROM t1
WHERE EXISTS (SELECT 1 FROM t3 WHERE t1.id = t3.id)
AND  NOT  EXISTS  (SELECT 1 FROM t2 WHERE t1.id = t2.id)
AND  NOT  EXISTS  (SELECT 1 FROM t4 WHERE t1.id = t4.id)

我将您最初的查询理解为要求“T1中的所有ID都在T1和T3中,但不在T2或T4中”。对吗?如果是,我的问题是:

SELECT DISTINCT t1.id
FROM t1
WHERE EXISTS (SELECT 1 FROM t3 WHERE t1.id = t3.id)
AND  NOT  EXISTS  (SELECT 1 FROM t2 WHERE t1.id = t2.id)
AND  NOT  EXISTS  (SELECT 1 FROM t4 WHERE t1.id = t4.id)

不确定真正的目标是什么,也不确定目标是哪个dbms

 -- oracle
SELECT id FROM ( SELECT id FROM t1 MINUS SELECT id FROM t2 ) a

INTERSECT

SELECT id FROM ( SELECT id FROM t3 MINUS SELECT id FROM t4 ) b
;

 -- sql server
SELECT id FROM ( SELECT id FROM t1 EXCEPT SELECT id FROM t2 ) a

INTERSECT

SELECT id FROM ( SELECT id FROM t3 EXCEPT SELECT id FROM t4 ) b
;

SELECT c.id from (

    SELECT t1.id
    FROM t1 LEFT JOIN t2 ON t1.id = t2.id
    WHERE t2.id IS NULL

    UNION ALL

    SELECT t3.id
    FROM t3 LEFT JOIN t4 ON t3.id = t4.id
    WHERE t4.id IS NULL

) c GROUP BY c.id HAVING count(*) >= 2
;
下一个可能相当有效,但有一个警告

-- conditions apply, assumes t2 and t4 cannot have ids not in t1 or t3 respectively
SELECT c.id from (

    SELECT a.id from (
      (SELECT ID FROM T1)
      UNION ALL 
      (SELECT ID FROM T2)
    ) a GROUP BY a.id HAVING count(*) = 1

    UNION ALL

    SELECT b.id from (
      (SELECT ID FROM T3)
      UNION ALL 
      (SELECT ID FROM T4)
    ) b GROUP BY b.id HAVING count(*) = 1

) c GROUP BY c.id HAVING count(*) >= 2
;
小提琴:

不确定真正的目标是什么,也不确定目标是哪个dbms

 -- oracle
SELECT id FROM ( SELECT id FROM t1 MINUS SELECT id FROM t2 ) a

INTERSECT

SELECT id FROM ( SELECT id FROM t3 MINUS SELECT id FROM t4 ) b
;

 -- sql server
SELECT id FROM ( SELECT id FROM t1 EXCEPT SELECT id FROM t2 ) a

INTERSECT

SELECT id FROM ( SELECT id FROM t3 EXCEPT SELECT id FROM t4 ) b
;

SELECT c.id from (

    SELECT t1.id
    FROM t1 LEFT JOIN t2 ON t1.id = t2.id
    WHERE t2.id IS NULL

    UNION ALL

    SELECT t3.id
    FROM t3 LEFT JOIN t4 ON t3.id = t4.id
    WHERE t4.id IS NULL

) c GROUP BY c.id HAVING count(*) >= 2
;
下一个可能相当有效,但有一个警告

-- conditions apply, assumes t2 and t4 cannot have ids not in t1 or t3 respectively
SELECT c.id from (

    SELECT a.id from (
      (SELECT ID FROM T1)
      UNION ALL 
      (SELECT ID FROM T2)
    ) a GROUP BY a.id HAVING count(*) = 1

    UNION ALL

    SELECT b.id from (
      (SELECT ID FROM T3)
      UNION ALL 
      (SELECT ID FROM T4)
    ) b GROUP BY b.id HAVING count(*) = 1

) c GROUP BY c.id HAVING count(*) >= 2
;
小提琴:

不确定真正的目标是什么,也不确定目标是哪个dbms

 -- oracle
SELECT id FROM ( SELECT id FROM t1 MINUS SELECT id FROM t2 ) a

INTERSECT

SELECT id FROM ( SELECT id FROM t3 MINUS SELECT id FROM t4 ) b
;

 -- sql server
SELECT id FROM ( SELECT id FROM t1 EXCEPT SELECT id FROM t2 ) a

INTERSECT

SELECT id FROM ( SELECT id FROM t3 EXCEPT SELECT id FROM t4 ) b
;

SELECT c.id from (

    SELECT t1.id
    FROM t1 LEFT JOIN t2 ON t1.id = t2.id
    WHERE t2.id IS NULL

    UNION ALL

    SELECT t3.id
    FROM t3 LEFT JOIN t4 ON t3.id = t4.id
    WHERE t4.id IS NULL

) c GROUP BY c.id HAVING count(*) >= 2
;
下一个可能相当有效,但有一个警告

-- conditions apply, assumes t2 and t4 cannot have ids not in t1 or t3 respectively
SELECT c.id from (

    SELECT a.id from (
      (SELECT ID FROM T1)
      UNION ALL 
      (SELECT ID FROM T2)
    ) a GROUP BY a.id HAVING count(*) = 1

    UNION ALL

    SELECT b.id from (
      (SELECT ID FROM T3)
      UNION ALL 
      (SELECT ID FROM T4)
    ) b GROUP BY b.id HAVING count(*) = 1

) c GROUP BY c.id HAVING count(*) >= 2
;
小提琴:

不确定真正的目标是什么,也不确定目标是哪个dbms

 -- oracle
SELECT id FROM ( SELECT id FROM t1 MINUS SELECT id FROM t2 ) a

INTERSECT

SELECT id FROM ( SELECT id FROM t3 MINUS SELECT id FROM t4 ) b
;

 -- sql server
SELECT id FROM ( SELECT id FROM t1 EXCEPT SELECT id FROM t2 ) a

INTERSECT

SELECT id FROM ( SELECT id FROM t3 EXCEPT SELECT id FROM t4 ) b
;

SELECT c.id from (

    SELECT t1.id
    FROM t1 LEFT JOIN t2 ON t1.id = t2.id
    WHERE t2.id IS NULL

    UNION ALL

    SELECT t3.id
    FROM t3 LEFT JOIN t4 ON t3.id = t4.id
    WHERE t4.id IS NULL

) c GROUP BY c.id HAVING count(*) >= 2
;
下一个可能相当有效,但有一个警告

-- conditions apply, assumes t2 and t4 cannot have ids not in t1 or t3 respectively
SELECT c.id from (

    SELECT a.id from (
      (SELECT ID FROM T1)
      UNION ALL 
      (SELECT ID FROM T2)
    ) a GROUP BY a.id HAVING count(*) = 1

    UNION ALL

    SELECT b.id from (
      (SELECT ID FROM T3)
      UNION ALL 
      (SELECT ID FROM T4)
    ) b GROUP BY b.id HAVING count(*) = 1

) c GROUP BY c.id HAVING count(*) >= 2
;
小提琴:

很抱歉,回复太晚。“您希望ID位于t1和t3中,但不在t2和t4中”=>是!我已经更新了我的问题。很抱歉回复晚了。“您希望ID位于t1和t3中,但不在t2和t4中”=>是!我已经更新了我的问题。很抱歉回复晚了。“您希望ID位于t1和t3中,但不在t2和t4中”=>是!我已经更新了我的问题。很抱歉回复晚了。“您希望ID位于t1和t3中,但不在t2和t4中”=>是!我已经更新了我的问题。谢谢你有时间<下一个产品中的一对多关系将考虑代码>半联接。我也更新了我的问题。谢谢你有时间<下一个产品中的一对多关系将考虑代码>半联接。我也更新了我的问题。谢谢你有时间<下一个产品中的一对多关系将考虑代码>半联接。我也更新了我的问题。谢谢你有时间<下一个产品中的一对多关系将考虑代码>半联接。我还更新了我的问题。关于修订/澄清的问题:我相信如果表中有多个相同id值,查询3将产生与查询1不同的结果。@turphile Oops。这是打字错误。固定的。谢谢。问题到底是什么?是这样吗:“我想知道这个查询在某些情况下有缺陷”你有失败的测试用例吗?@Used\u By\u已经感谢你抽出时间。“问题到底是什么?”=>我想知道3个查询是相同的。“您有任何失败测试用例吗?”=>还没有。但我不确定TC是否成功,因为测试数据集不足。类似的问题也存在。他提出的3个问题与FROM子条款中的其他排列完全相同。我只想知道查询1~3是相同的。对不起,英语不好。谢谢。关于修改/澄清的问题:我相信如果表中有多个相同id值,查询3将产生与查询1不同的结果。@Turophile Oops。这是打字错误。固定的。谢谢。问题到底是什么?是这样吗:“我想知道这个查询在某些情况下有缺陷”你有失败的测试用例吗?@Used\u By\u已经感谢你抽出时间。“问题到底是什么?”=>我想知道3个查询是相同的。“您有任何失败测试用例吗?”=>还没有。但我不确定TC是否成功,因为测试数据集不足。类似的问题也存在。他提出的3个问题与FROM子条款中的其他排列完全相同。我只想知道查询1~3是相同的。对不起,英语不好。谢谢。关于修改/澄清的问题:我相信如果表中有多个相同id值,查询3将产生与查询1不同的结果。@Turophile Oops。这是打字错误。固定的。谢谢。问题到底是什么?是这样吗:“我想知道这个查询在某些情况下有缺陷”你有失败的测试用例吗?@Used\u By\u已经感谢你抽出时间。“问题到底是什么?”=>我想知道3个查询是s