我的父/子表看起来像这样:
CREATE TABLE users(
id integer primary key AUTOINCREMENT,
pnum varchar(10),
dloc varchar(100),
cc varchar(10),
name varchar(255),
group active bit(1)
);
CREATE TABLE group_members(
id integer primary key AUTOINCREMENT,
group_id integer,
member_id integer,
FOREIGN KEY (group_id) REFERENCES users(id),
FOREIGN KEY (member_id) REFERENCES users(id)
);
用户数据如下:
ID PNUM DLOC CC NAME GRP
86|23101|dloc 89| | |0
87|23101|dloc 90| | |0
88|23102|dloc 91| | |0
590|12345|Group | |Test Group|1
591|90000|dloc 1 | | |0
group_members数据如下:
ID GROUP_ID
1 |590 | 87
2 |590 | 88
基于PNUM,我希望能够为所有用户获取dloc值,无论是否为组。
例如,如果有人请求pnum 23101,我想回来
但如果他们要求12345,我想回来
到目前为止,我已经提出了这个问题:
SELECT users.dloc
FROM users
WHERE users.id IN
(SELECT group_members.member_id
FROM group_members
INNER JOIN users on users.id = group_members.group_id
WHERE users.pnum='12345');
适用于群组,但如果我使用pnum 23101运行相同的查询,则不会返回任何结果。
到目前为止我尝试了什么
我试着看看我是否可以这样使用OR:
SELECT users.dloc
FROM users
WHERE users.id in
(SELECT group_members.member_id
FROM group_members
INNER JOIN users on users.id = group_members.group_id
WHERE users.pnum='12345');
OR
(SELECT users.dloc
FROM users
WHERE pnum='12345')
任何建议将不胜感激。
答案 0 :(得分:0)
您可以使用UNION
执行两个查询,其中一个查询直接在PNUM
上匹配GROUP <> 1
的值,另一个匹配{ {1}}并通过PNUM
加入group_members
。
在第二部分中,您需要加入两次GROUP = 1
以使该组的成员与原始users
匹配。
由于每个PNUM
条件相反,GROUP
中只有一部分会返回结果。
UNION
遗憾的是,这需要在查询中放置/* First part of UNION directly matches PNUM for GROUP = 0 */
SELECT dloc
FROM users
WHERE
PNUM = 23101
AND `group` <> 1
UNION
/**
Second part of UNION matches GROUP = 1
and joins through group_members back to users
to get member dloc (from the second users join)
*/
SELECT uu.dloc
FROM users u
INNER JOIN group_members m ON u.`GROUP` = 1 AND u.id = m.group_id
INNER JOIN users uu ON m.member_id = uu.id
WHERE
u.PNUM = 23101
值两次,每PNUM
部分一次,但这并不是那么糟糕。
Here it is in action(使用MySQL而不是SQLite,但这并不重要)
将原始方法与UNION
和OR
子查询一起使用,也可以完成,但我为IN()
和{{1}添加了WHERE
个条件}。
GROUP = 0