我已经尝试查看已经建议的所有“重复项”,但无法找到正确的查询。
为了简单起见,我将我的问题翻译成了另一个 - 所以我不是在寻找一种不同的方式来构建我的数据,而是根据现有的模式来查询它。
复制问题的代码以及我尝试的查询位于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 friend_id friend_name enemy_id enemy_name p1 tom f1p1 toms friend 1 None None p1 tom f2p1 toms friend 2 None None p1 tom f3p1 toms friend 3 None None p1 tom f4p1 toms friend 4 None None p1 tom None None e1p1 toms enemy 1 p1 tom None None e2p1 toms enemy 2 p1 tom None None e3p1 toms enemy 3 p1 tom None NOne e4p1 toms enemy 4 p2 sam f1p2 sams friend 1 None None p2 sam f2p2 sams friend 2 None None p2 sam f3p2 sams friend 3 None None p2 sam f4p2 sams friend 4 None None p2 sam None None e1p2 sams enemy 1 p2 sam None None e2p2 sams enemy 2 p2 sam None None e3p2 sams enemy 3 p2 sam None None e4p2 sams enemy 4 p3 tim None None e1p3 tims enemy 1
答案 0 :(得分: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
排序可确保非空朋友行在空行之前排序。)