[英]Return all rows in MySQL LEFT JOIN query (table self-join)
我在 MySQL 8 中有以下分層表結構“ nato ”:
INSERT INTO `nato`(`id`, `parentID`, `level`, `name`, `has_children`) VALUES (1, NULL, 0, 'Charlie', 1);
INSERT INTO `nato`(`id`, `parentID`, `level`, `name`, `has_children`) VALUES (2, NULL, 0, 'Echo', 1);
INSERT INTO `nato`(`id`, `parentID`, `level`, `name`, `has_children`) VALUES (3, 1, 1, 'Alpha', 0);
INSERT INTO `nato`(`id`, `parentID`, `level`, `name`, `has_children`) VALUES (4, 1, 1, 'Tango', 1);
INSERT INTO `nato`(`id`, `parentID`, `level`, `name`, `has_children`) VALUES (5, 2, 1, 'Papa', 1);
INSERT INTO `nato`(`id`, `parentID`, `level`, `name`, `has_children`) VALUES (6, 1, 1, 'Foxtrot', 1);
INSERT INTO `nato`(`id`, `parentID`, `level`, `name`, `has_children`) VALUES (7, NULL, 0, 'Uniform', 0);
INSERT INTO `nato`(`id`, `parentID`, `level`, `name`, `has_children`) VALUES (8, 2, 1, 'Lima', 0);
INSERT INTO `nato`(`id`, `parentID`, `level`, `name`, `has_children`) VALUES (9, 4, 2, 'Sierra', 0);
INSERT INTO `nato`(`id`, `parentID`, `level`, `name`, `has_children`) VALUES (10, 5, 2, 'Juliet', 0);
INSERT INTO `nato`(`id`, `parentID`, `level`, `name`, `has_children`) VALUES (11, 6, 2, 'India', 0);
INSERT INTO `nato`(`id`, `parentID`, `level`, `name`, `has_children`) VALUES (12, 6, 2, 'Oscar', 0);
(我有什么:)
id parentID level name has_children
1 (null) 0 Charlie 1
2 (null) 0 Echo 1
3 1 1 Alpha 0
4 1 1 Tango 1
5 2 1 Papa 1
6 1 1 Foxtrot 1
7 (null) 0 Uniform 0
8 2 1 Lima 0
9 4 2 Sierra 0
10 5 2 Juliet 0
11 6 2 India 0
12 6 2 Oscar 0
我正在針對它運行以下查詢,其中 L0 是 0 級等:(我嘗試了什么:)
SELECT f.id AS L0_id,
f.NAME AS L0_name,
f1.id AS L1_id,
f1.NAME AS L1_name,
f2.id AS L2_id,
f2.NAME AS L2_name
FROM nato f
LEFT JOIN nato f1
ON f1.parentID = f.id
LEFT JOIN nato f2
ON f2.parentID = f1.id
WHERE f.parentID IS NULL
ORDER BY l0_id ASC
獲得跨級別“L0”到“L2”的結果:(我得到了什么:)
L0_id L0_name L1_id L1_name L2_id L2_name
1 Charlie 3 Alpha (null) (null)
1 Charlie 4 Tango 9 Sierra
1 Charlie 6 Foxtrot 11 India
1 Charlie 6 Foxtrot 12 Oscar
2 Echo 5 Papa 10 Juliet
2 Echo 8 Lima (null) (null)
7 Uniform (null) (null) (null) (null)
我希望獲得的是每個帶有孩子的項目的一行(類似於 Uniform 的行),以 id 的遞增順序,即(我期望得到的)
L0_id L0_name L1_id L1_name L2_id L2_name
1 Charlie (null) (null) (null) (null)
1 Charlie 3 Alpha (null) (null)
1 Charlie 4 Tango (null) (null)
1 Charlie 4 Tango 9 Sierra
1 Charlie 6 Foxtrot (null) (null)
1 Charlie 6 Foxtrot 11 India
1 Charlie 6 Foxtrot 12 Oscar
2 Echo (null) (null) (null) (null)
2 Echo 4 Papa (null) (null)
2 Echo 5 Papa 10 Juliet
2 Echo 8 Lima (null) (null)
7 Uniform (null) (null) (null) (null)
如何修改我的查詢以實現上述結果? 如果這會使事情變得更容易,我已經添加了兩列( level和has_children ),但我仍然不確定如何實現我的目標。 提前致謝。
這是我最終使用兩個 UNION 拼湊出來的。 很可能不是最有效的方法,但我希望它對其他人有所幫助。
SELECT
f.id as L_id,
f.name as L_name,
f1.id as L1_id,
f1.name as L1_name,
f2.id as L2_id,
f2.name as L2_name
FROM
nato f
LEFT JOIN nato f1
ON f1.parentID = f.id
LEFT JOIN nato f2
ON f2.parentID = f1.id
WHERE
f.parentID IS NULL
UNION
SELECT f.id as L_id,
f.name as L_name,
NULL as L1_id,
NULL as L1_name,
NULL as L2_name,
NULL as L2_name
FROM nato f
WHERE f.parentID IS NULL
AND f.has_children = 1
UNION
SELECT f.id as L_id,
f.name as L_name,
f1.id as L1_id,
f1.name as L1_name,
NULL as L2_name,
NULL as L2_name
FROM nato f
LEFT JOIN nato f1
ON f1.parentID = f.id
WHERE f.parentID IS NULL
AND f1.has_children = 1
ORDER BY
L_id,L1_id,L2_id ASC
產生預期的結果:
L_id L_name L1_id L1_name L2_id L2_name
1 Charlie (null) (null) (null) (null)
1 Charlie 3 Alpha (null) (null)
1 Charlie 4 Tango (null) (null)
1 Charlie 4 Tango 9 Sierra
1 Charlie 6 Foxtrot (null) (null)
1 Charlie 6 Foxtrot 11 India
1 Charlie 6 Foxtrot 12 Oscar
2 Echo (null) (null) (null) (null)
2 Echo 4 Papa (null) (null)
2 Echo 5 Papa 10 Juliet
2 Echo 8 Lima (null) (null)
7 Uniform (null) (null) (null) (null)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.