我尝试查看已经建议的所有“重复项”,但无法为此找到正确的查询。
为了简单起见,我将问题转换为其他问题-因此,我并不是在寻找结构数据的其他方法,而是在给定现有模式的情况下查询数据的方法。
复制问题以及我尝试过的查询的代码位于here。
给定以下架构
CREATE TABLE PERSONS(id, name, c1, c2);
CREATE TABLE FRIENDS(id, person_id, name, c1, c2);
CREATE TABLE ENEMIES(id, person_id, name, c1, c2);
和一些示例数据(仅用于打印sqlite以便将其打印出来-我通过代码中的python进行通信)
sqlite> select * from PERSONS;
p1|tom|p1c1v|p1c2v
p2|sam|p2c1v|p2c2v
p3|tim|p3c1v|p3c2v
sqlite> select * from FRIENDS;
f1p1|p1|toms friend 1|f1p1c1v|f1p1c2v
f2p1|p1|toms friend 2|f2p1c1v|f2p1c2v
f3p1|p1|toms friend 3|f3p1c1v|f3p1c2v
f4p1|p1|toms friend 4|f4p1c1v|f4p1c2v
f1p2|p2|sams friend 1|f1p2c1v|f1p2c2v
f2p2|p2|sams friend 2|f2p2c1v|f2p2c2v
f3p2|p2|sams friend 3|f3p2c1v|f3p2c2v
f4p2|p2|sams friend 4|f4p2c1v|f4p2c2v
sqlite> select * from ENEMIES;
e1p1|p1|toms enemy 1|e1p1c1v|e1p1c2v
e2p1|p1|toms enemy 2|e2p1c1v|e2p1c2v
e3p1|p1|toms enemy 3|e3p1c1v|e3p1c2v
e4p1|p1|toms enemy 4|e4p1c1v|e4p1c2v
e1p2|p2|sams enemy 1|e1p2c1v|e1p2c2v
e2p2|p2|sams enemy 2|e2p2c1v|e2p2c2v
e3p2|p2|sams enemy 3|e3p2c1v|e3p2c2v
e4p2|p2|sams enemy 4|e4p2c1v|e4p2c2v
e1p3|p3|tims enemy 1|e1p3c1v|e1p3c2v
我希望能够遍历人员表,并让每个人都得到所有的朋友和敌人。 (我希望在一个查询中这样做,因为我不想对每个人的朋友和敌人表进行多次查询)。
p1 tom p1c1v p1c2v
(some information about toms friends) together
[
f1p1 "toms friend 1"
f2p1 "toms friend 2"
f3p1 "toms friend 3"
f4p1 "toms friend 4"
]
(some information about toms enemies) togetner
[
e1p1 "toms enemy 1"
e2p1 "toms enemy 2"
e3p1 "toms enemy 3"
e4p1 "toms enemy 4"
]
如the code所示,我已经通过sqlite尝试了这些查询
SELECT p.id, p.name, f.id, f.person_id, f.name, e.id, e.person_id, e.name
FROM persons as p
LEFT JOIN friends as f on p.id = f.person_id
LEFT JOIN enemies as e on p.id = e.id
GROUP BY p.id
但是此查询只返回该ID的一行,这是我不想要的,我想要所有的行。
删除GROUP BY时,我确实得到了很多行,但没有敌人信息。
本质上,我需要以下内容,但是作为一个查询(不更改现有架构-添加索引除外)
for person_row in "select * from persons"
friend_rows_for_person = "select * from friends where person_id=person_row.id"
enemies_rows_for_person = "select * from enemies where person_id=person_row.id"
# I continue processing this person with friends
# and enemies before moving on to the next person
预期产量:
person_id person_name朋友编号id朋友名称敌人ID敌人名称
p1 tom f1p1 toms朋友1无无
p1 tom f2p1 toms朋友2无无
p1 tom f3p1 toms朋友3无无
p1 tom f4p1 toms朋友4无无
p1 tom无无e1p1 toms敌人1
p1 tom无无e2p1 toms敌人2
p1 tom无无e3p1 toms敌人3
p1 tom无NOne e4p1 toms敌人4
p2 sam f1p2 sams朋友1无无
p2 sam f2p2 sams朋友2无无
p2 sam f3p2 sams朋友3无无
p2 sam f4p2 sams朋友4无无
p2 sam无无e1p2击沉敌人1
p2 sam无无e2p2 sams敌人2
p2 sam无无e3p2 sams敌人3
p2 sam无无e4p2击沉敌人4
p3 tim无无e1p3 tims敌人1
最佳答案
这实质上是两个查询,合并为一个查询。
您需要使用compound query:
SELECT persons.id AS person_id,
persons.name AS person_name,
friends.id AS friend_id,
friends.name AS friend_name,
NULL AS enemy_id,
NULL AS enemy_name,
friends.id IS NULL -- needed for sorting
FROM persons
JOIN friends ON persons.id = friends.person_id
UNION ALL
SELECT persons.id,
persons.name,
enemies.id,
enemies.name,
NULL,
NULL,
NULL
FROM persons
JOIN enemies ON persons.id = enemies.person_id
ORDER BY persons.id,
friends.id IS NULL,
friends.id,
enemies.id;
(按
friends.id IS NULL
排序可确保非NULL朋友行排在空行之前。)