我使用postgres 9.5。 我需要存储这样的(树状)数据:
等级1b
1c级
这是我的sql表:
CREATE TABLE matieres_test (
id serial NOT NULL CONSTRAINT matieres_test_id_pk PRIMARY KEY,
name varchar NOT NULL,
parent INT DEFAULT NULL,
CONSTRAINT matieres_test_parent_fk FOREIGN KEY (parent) REFERENCES matieres_test(id)
);
并插入(如果易于阅读,则列表)
insert into matieres_test(id,name,parent) values (1,'level 1a',null);
insert into matieres_test(id,name,parent) values (5,'level 2a ',1);
insert into matieres_test(id,name,parent) values (9,'level 3a',5);
insert into matieres_test(id,name,parent) values (10,'level 3b',5);
insert into matieres_test(id,name,parent) values (6,'level 2b', 1);
insert into matieres_test(id,name,parent) values (2,'level 1b',null);
insert into matieres_test(id,name,parent) values (7,'level 2a',2);
insert into matieres_test(id,name,parent) values (8,'level 2b',2);
insert into matieres_test(id,name,parent) values (3,'level 1c',null);
insert into matieres_test(id,name,parent) values (4,'level 1d',null);
现在我想获取数据,我的查询:
SELECT t1.name AS lev1, t2.name as lev2, t3.name as lev3, t4.name as lev4
FROM matieres_test AS t1
LEFT JOIN matieres_test AS t2 ON t2.parent = t1.id
LEFT JOIN matieres_test AS t3 ON t3.parent = t2.id
LEFT JOIN matieres_test AS t4 ON t4.parent = t3.id
结果:
| lev1 | lev2 | lev3
----|-----------|-----------|----------
1 | level 1a | level 2a | level 3b
2 | level 1a | level 2a | level 3a
3 | level 2a | level 3b |
4 | level 1b | level 2b |
5 | level 1a | level 2b |
6 | level 1b | level 2a |
7 | level 2a | level 3a |
8 | level 3b |
9 | level 2b |
10 | level 2b |
11 | level 2a |
12 | level 1d |
13 | level 1c |
14 | level 3a |
问题是它返回错误的行(第3,7,8,9,10,11,14行) 因为我在“lev1”栏等中得到“等级2a”......
我需要这样的东西:
| lev1 | lev2 | lev3
----|-----------|-----------|----------
| level 1a | level 2a | level 3a
| level 1a | level 2a | level 3b
| level 1a | level 2b |
| level 1b | level 2a |
| level 1b | level 2b |
| level 1d |
| level 1c |
请问好吗?
答案 0 :(得分:2)
看起来您需要做的就是约束查询,以便lev1
记录null
为parent
:
SELECT t1.name AS lev1, t2.name as lev2, t3.name as lev3, t4.name as lev4
FROM matieres_test AS t1
LEFT JOIN matieres_test AS t2 ON t2.parent = t1.id
LEFT JOIN matieres_test AS t3 ON t3.parent = t2.id
LEFT JOIN matieres_test AS t4 ON t4.parent = t3.id
WHERE t1.parent IS NULL -- add this condition
-- and an optional ORDER BY clause if you need the result in a specific order...
添加where
子句后,结果变为:
lev1 lev2 lev3 lev4
---------- ---------- ---------- ----------
level 1a level 2a level 3a NULL
level 1a level 2a level 3b NULL
level 1a level 2b NULL NULL
level 1b level 2a NULL NULL
level 1b level 2b NULL NULL
level 1c NULL NULL NULL
level 1d NULL NULL NULL
答案 1 :(得分:1)
SELECT DISTINCT
t1.name AS lev1,
t2.name AS lev2,
t3.name AS lev3,
t4.name AS lev4
FROM matieres_test AS t1
LEFT JOIN matieres_test AS t2
ON t2.parent = t1.id
LEFT JOIN matieres_test AS t3
ON t3.parent = t2.id
LEFT JOIN matieres_test AS t4
ON t4.parent = t3.id
WHERE t1.parent IS NULL
ORDER BY lev1, lev2, lev3, lev4;
您必须为t1.parent添加IS NULL
项检查。使用给定的ORDER BY
子句,您可以正确地对结果进行排序。