【问题标题】:JOIN statement with OR statement带有 OR 语句的 JOIN 语句
【发布时间】:2018-06-07 16:45:49
【问题描述】:

我正在尝试解决一个 JOIN 问题,我需要在连接中使用 or 语句。

我有 2 张桌子。表 1 有大约 1000 条记录,表 2 有数百万条记录。

表 1 有 2 个字段(claim1、claim2),如果其中任何一个字段与表 2.claim 字段匹配,那么我需要将 table2.field1 和 table2.field2 值插入到临时表中。

假设我有这两张表

    table 1 claim1  claim2      table 2 claim   field1  field2
              1001    2001          1001    a1  a2
              1002    2002          1002    b1  b2
              1003    2003          1003    c1  c2
                                    2001    d1  d2
                                    2002    e1  e2

我正在尝试从表 2 中获取表 1 中声明 1 和声明 2 字段的记录的值。

所以我写了这个

SELECT CLAIM, FIELD1, FIELD2
FROM TABLE1 T1
JOIN TABLE2 T2 ON T2.CLAIM = T1.CLAIM1 
                OR T2.CLAIM = T1.CLAIM2​

如果我只是运行它,它会在几秒钟内运行,然后我会取回记录。

SELECT CLAIM, FIELD1, FIELD2
FROM TABLE1 T1
JOIN TABLE2 T2 ON T2.CLAIM = T1.CLAIM1 

添加 or 语句后,我在大约 15 分钟后终止了查询。

SELECT CLAIM, FIELD1, FIELD2
FROM TABLE1 T1
JOIN TABLE2 T2 ON T2.CLAIM = T1.CLAIM1 
                OR T2.CLAIM = T1.CLAIM2​

任何帮助将不胜感激。我只是想花点时间思考这个问题

【问题讨论】:

  • 您可以有两个单独的查询并尝试使用 UNION 而不是使用 OR。
  • 请标记您的 DBMS(包括版本)
  • In 对于性能来说是一个不错的选择,它不如两个语句快,但比 or 快。即T2.CLAIM in (T1.CLAIM,T1.CLAIM2)
  • 也许在 claim1 和 claim2 上做一个 select distinct 到一个单独的第一个临时表中,只是将别名字段命名为每个 tume 然后在第二个临时表中做一个 select distinct 到第二个临时表中。然后将其加入您的表 2。或者只是在其中使用 select claim from temp2 执行嵌套的 in 子句

标签: sql join


【解决方案1】:

OR 是性能杀手,尤其是JOINs。你可以通过两个LEFT JOINs 来解决这个问题:

SELECT COALESCE(T2_1.CLAIM, T2_2.CLAIM) as CLAIM,
       COALESCE(T2_1.FIELD1, T2_2.FIELD1) as FIELD1,
       COALESCE(T2_1.FIELD2, T2_2.FIELD2) as FIELD2
FROM TABLE1 T1 LEFT JOIN
     TABLE2 T2_1
     ON T2_1.CLAIM = T1.CLAIM1 LEFT JOIN
     TABLE2 T2_2
     ON T2_2.CLAIM = T1.CLAIM2​ AND T2_1.CLAIM IS NULL
WHERE T2_1.CLAIM IS NOT NULL OR T2_2.CLAIM IS NOT NULL;

奇怪的是,您没有从TABLE1 中选择任何字段。

【讨论】:

    【解决方案2】:

    请检查此 SQL:

    SELECT CLAIM, FIELD1, FIELD2 FROM TABLE1 JOIN TABLE2 ON TABLE1.CLAIM1 = TABLE2.CLAIM
    UNION ALL
    SELECT CLAIM, FIELD1, FIELD2 FROM TABLE1 JOIN TABLE2 ON TABLE1.CLAIM2 = TABLE2.CLAIM
    

    应该可以了!

    但是,我认为查询中必须包含父 TABLE1 表的更多列。因为在给定的示例中,此查询将像过滤器一样工作。一个过滤器,它将确保 TEMP TABLE 中附加的 TABLE2 的所有记录在父 TABLE1 中至少有一条记录。 p>

    如果您以完整性管理数据,那么结果将与SELECT * FROM TABLE2 相同。

    【讨论】:

    • SELECT * FROM TABLE2 将不起作用,因为如果表 1 中有该声明的记录,我只需要表 2 中的值。
    • 我知道这会起作用 SELECT CLAIM, FIELD1, FIELD2 FROM TABLE1 JOIN TABLE2 ON TABLE1.CLAIM1 = TABLE2.CLAIM UNION ALL SELECT CLAIM, FIELD1, FIELD2 FROM TABLE1 JOIN TABLE2 ON TABLE1.CLAIM2 = TABLE2。索赔,我只是不知道为什么会或不是。
    • 亲爱的!我的意思是“如果您以诚信的方式管理数据,那么......”。我没有发布它作为你的答案。答案是第一条 SQL 语句。如果你不明白我的意思,那就离开它并尝试我的第一个 SQL 语句。
    猜你喜欢
    • 2017-08-15
    • 1970-01-01
    • 2017-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多