代码之家  ›  专栏  ›  技术社区  ›  One Two Three

在嵌套查询中创建和使用临时表

  •  1
  • One Two Three  · 技术社区  · 12 年前

    我有一个查询,其中 MINUS 运算符被计算两次。 如何重写查询,使其只创建一次?

    (目的是检查这两个集合是否相等)

    SELECT DISTINCT t1.id
    FROM t1
    WHERE NOT EXISTS (SELECT t2.did FROM t1 AS t2
                  WHERE t2.id = t1.id
                  MINUS
                  SELECT t3.did FROM t3
                  WHERE t3.price > 500000)
    AND NOT EXISTS (SELECT t3.did FROM t3
                WHERE t3.price > 500000
                MINUS
                SELECT t2.did FROM t1 AS t2
                WHERE t2.id = t1.id);
    

    为了澄清问题,以下两个[子]查询在查询中重复两次:

    SELECT t2.did FROM t1 AS t2
    WHERE t2.id = t1.id
    

    SELECT t3.did FROM t3
    WHERE t3.price > 500000
    
    3 回复  |  直到 12 年前
        1
  •  2
  •   Egor Skriptunoff    12 年前
    with
       ALL_DID as (
          select did from t3
          where price > 500000
       ),
       PAIRS as (
          select
             id, t3.did
          from t1
             left join ALL_DID t3
             on t1.did = t3.did
       )
    select id from PAIRS
       group by id
       having count(did) = (
          select count(0) from ALL_DID
       )
    minus
    select id from PAIRS
       where did is null
    

    fiddle

        2
  •  0
  •   sgeddes    12 年前

    如果您只想多次重用同一查询,请考虑使用公共表表达式。或者,您可以考虑创建视图。这些方法可以快速“重用”同一个查询。

    然而,我仍然不完全理解你想要的结果。你想知道t1中的数据是否与t3中的数据相同吗?基于did/eid字段?如果是这样的话,似乎可以使用LEFT JOIN来更容易地解决这个问题。类似这样的内容:

    SELECT DISTINCT t1.id
    FROM t1 
      LEFT JOIN t3 ON t1.did = t3.did AND t3.price > 500000
    WHERE t3.id IS NULL
    

    这将告诉你t1中是否有任何不在t3中的记录(相同,价格>500000)。

    编辑-要查找所有销售价格超过500000的产品的人员的id,则此操作应该有效:

    SELECT t1.id, COUNT(DISTINCT t1.did) productcnt
    FROM t1
      JOIN t3 ON t1.did = t3.did
    WHERE t3.Price > 500000
    GROUP BY t1.id
    HAVING COUNT(DISTINCT t1.did) = (
      SELECT COUNT(DISTINCT did) cnt
      FROM t3
      WHERE Price > 500000 )
    

    SQL Fiddle Demo

        3
  •  -1
  •   georgecj11    12 年前

    这不是正常的内部联接查询吗?

    SELECT t2.* 
    from t1
    INNER JOIN t3 as t3 on t1.did = t3.tid
    INNER JOIN t1 as t2 on t2.did = t1.id
    WHERE t3.price > 50000