如何减少 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 并不总是需要删除的东西。
如果您将查询更改为使用 JOIN
s,那么您可能会得到不同的结果,因为 JOIN
ed 查询然后可以 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
但是如果你使用JOIN
s:
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
我要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 并不总是需要删除的东西。
如果您将查询更改为使用 JOIN
s,那么您可能会得到不同的结果,因为 JOIN
ed 查询然后可以 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
但是如果你使用JOIN
s:
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