【发布时间】:2021-05-29 00:13:52
【问题描述】:
有两个 MySQL 表:
tparent(id int, some data...)
tchild(id int, parent_id int, some data...)
我需要返回至少有一个子项符合某些条件的所有列(父项加上所有子项)。
我目前的解决方案:
-- prepare sample data
DROP TABLE IF EXISTS tparent;
DROP TABLE IF EXISTS tchild;
CREATE TABLE tparent (id int, c1 varchar(10), c2 date, c3 float);
CREATE TABLE tchild(id int, parent_id int, c4 float, c5 varchar(20), c6 date);
CREATE UNIQUE INDEX tparent_id_IDX USING BTREE ON tparent (id);
CREATE UNIQUE INDEX tchild_id_IDX USING BTREE ON tchild (id);
INSERT INTO tparent
VALUES
(1, 'a', '2021-01-01', 1.23)
, (2, 'b', '2021-02-01', 1.32)
, (3, 'c', '2021-01-03', 2.31);
INSERT INTO tchild
VALUES
(10, 1, 22.333, 'argh1', '2000-01-01')
, (20, 1, 33.222, 'argh2', '2000-01-02')
, (30, 1, 44.555, 'argh3', '2000-02-02')
, (40, 2, 33.222, 'argh4', '2000-03-02')
, (50, 3, 33.222, 'argh5', '2000-04-02')
, (60, 3, 33.222, 'argh6', '2000-05-02');
-- the query
WITH parent_filter AS
(
SELECT
parent_id
FROM
tchild
WHERE
c4>44
)
SELECT
p.*,
c.*
FROM
tparent p
JOIN tchild c ON p.id = c.parent_id
JOIN parent_filter pf ON p.id = pf.parent_id;
它为父 id 1 和子 id 10、20、30 返回 3 行,因为子 id 30 具有匹配记录。它不会返回任何其他父 ID 的数据。
但是,我在这里查询了两次tchild(首先在 CTE 中,然后再次在主查询中)。由于两个表都比较大(10 到 1 亿行,每个父记录平均有 2-5 个子记录),我遇到了性能/时间问题。
有没有更好的方法来实现这种过滤? IE。无需多次查询tchild 表?
【问题讨论】:
-
公平点,问题现已更新为可重现的示例
-
它不返回任何其他父级,因为 30 是唯一具有 c4 > 40 的父级
-
没错,这就是我需要的。我需要包含所有父记录,其中至少一个子记录符合条件。
标签: mysql sql filtering inner-join query-optimization