如何减少 SQL 中的子查询数量

how to reduce the number of sub queries in SQL

我要optimize/reduce子查询:

select cash from INFO where cid IN (
    select tid from activity where point='aaa' and stats='bbb' and tid IN (
        select rid from request where stats in ('vvv','ddd') and TS >= to date ('2022-05-04','YYYY-DD-MM')))

加入,我想。

SELECT i.cash
  FROM info i
       JOIN activity a ON a.tid = i.cid
       JOIN request r ON r.rid = a.tid
 WHERE     a.point = 'aaa'
       AND a.stats = 'bbb'
       AND r.stats IN ('vvv', 'ddd')
       AND r.ts >= DATE '2022-04-05'

您无需执行任何操作,因为查询已按原样进行了优化,并且 sub-queries 并不总是需要删除的东西。


如果您将查询更改为使用 JOINs,那么您可能会得到不同的结果,因为 JOINed 查询然后可以 return 重复您以前想要的行只有唯一的行。

例如,如果您有数据:

CREATE TABLE info (cash, cid PRIMARY KEY) AS
SELECT 100, 1 FROM DUAL;

CREATE TABLE activity (id PRIMARY KEY, tid, point, stats) AS
SELECT 2, 1, 'aaa', 'bbb' FROM DUAL;

CREATE TABLE request (id PRIMARY KEY, rid, ts, stats) AS
SELECT 3, 1, DATE '2022-04-05', 'vvv' FROM DUAL UNION ALL
SELECT 4, 1, DATE '2022-04-06', 'ddd' FROM DUAL;

那么您的查询:

SELECT cash
FROM   INFO
WHERE  cid IN (
         SELECT tid
         FROM   activity
         WHERE  point='aaa'
         AND    stats='bbb'
         AND    tid IN (
                  SELECT rid
                  FROM   request
                  WHERE  stats in ('vvv','ddd')
                  AND    TS >= DATE '2022-04-05'
                )
       );

输出:

CASH
100

但是如果你使用JOINs:

SELECT i.cash
FROM   info i
       JOIN activity a ON a.tid = i.cid
       JOIN request r ON r.rid = a.tid
WHERE  a.point = 'aaa'
AND    a.stats = 'bbb'
AND    r.stats IN ('vvv', 'ddd')
AND    r.ts >= DATE '2022-04-05'

则输出为:

CASH
100
100

因为 cash 中的一行被连接到 activity 中的一行,而 activity 中的一行又被连接到 request 中的两行并且这两行都是 returned。


您可能已经摆脱了 sub-queries 但您得到了不同的输出!

db<>fiddle here