如何改进具有多个子查询的 SELECT 语句

Posted

技术标签:

【中文标题】如何改进具有多个子查询的 SELECT 语句【英文标题】:How to improve SELECT statements with multiple sub-queries 【发布时间】:2019-02-13 13:15:20 【问题描述】:

如何更好地改进以下 SQL 语句?我曾尝试使用 EXCEPT,但它不起作用。非常欢迎任何建议/建议!

SELECT COUNT(*)
FROM ( SELECT L_ORDERKEY, COUNT(*)
   FROM LINEITEM
   GROUP BY L_ORDERKEY
   HAVING COUNT(*) > (SELECT DISTINCT TSIZE
                      FROM LINEITEM) );


SELECT LINEITEM.L_ORDERKEY, LINEITEM.L_LINENUMBER
FROM LINEITEM JOIN PART
   ON LINEITEM.L_PARTKEY = PART.P_PARTKEY
WHERE PART.P_PARTKEY IN (46557,20193,19110,45690,45123)
   MINUS
      (SELECT LINEITEM.L_ORDERKEY, LINEITEM.L_LINENUMBER
       FROM LINEITEM JOIN PART
          ON LINEITEM.L_PARTKEY = PART.P_PARTKEY
       WHERE PART.P_PARTKEY IN (46557,20193,19110,45690,45123)
       MINUS
       SELECT LINEITEM.L_ORDERKEY, LINEITEM.L_LINENUMBER
       FROM LINEITEM JOIN SUPPLIER
          ON LINEITEM.L_SUPPKEY = SUPPLIER.S_SUPPKEY
       WHERE SUPPLIER.S_SUPPKEY IN (4567,2323,1987,2194,1111)
      );

【问题讨论】:

你能给我们提供一些你的桌子的例子吗?你想要什么?我看到你有两个子查询一个在另一个,但第三个不在“(...)”内 @AurelianoGuedes 你好!我的桌子很大,因此被排除在外。我只是想看看是否有更好的方法来处理这些子查询而无需太多子查询。想知道如何更好地做到这一点会很好。 @AurelianoGuedes 你说的“(...)”是什么意思?有什么问题吗? 【参考方案1】:

第二个查询可以使用not exists

   SELECT L.L_ORDERKEY, L.L_LINENUMBER
     FROM LINEITEM L
     JOIN PART P
       ON L.L_PARTKEY = P.P_PARTKEY
    WHERE P.P_PARTKEY IN (46557, 20193, 19110, 45690, 45123)
      AND NOT EXISTS
         (SELECT 0
            FROM SUPPLIER S
           WHERE S.S_SUPPKEY IN (4567, 2323, 1987, 2194, 1111)
             AND L.L_SUPPKEY = S.S_SUPPKEY );

【讨论】:

以上是关于如何改进具有多个子查询的 SELECT 语句的主要内容,如果未能解决你的问题,请参考以下文章

使用子查询改进 MySql 查询左外连接

SQL Case 语句子选择内的子选择分组

oracle数据库如何按多个条件查询数据。

请教怎么写跨库查询的SQL语句

Postgresql:FROM 中的子查询必须有别名 - 具有多个连接

如何在具有子查询的以下查询中不使用 DB