从父/子表中选择记录

时间:2015-05-15 18:31:59

标签: sql sqlite join

我的父/子表看起来像这样:

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,我想回来

  • “dloc 89”和
  • “dloc 90”

但如果他们要求12345,我想回来

  • “dloc 90”和
  • “dloc 91”

到目前为止,我已经提出了这个问题:

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')

任何建议将不胜感激。

1 个答案:

答案 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,但这并不重要)

将原始方法与UNIONOR子查询一起使用,也可以完成,但我为IN()和{{1}添加了WHERE个条件}。

GROUP = 0

And here's the alternative method in action...