2014-01-25 164 views
0

我想创建一个SELECT语句,但我不确定如何完成它。SQL复杂的select语句

我有2个表格,usergroup。每个用户都有一个userid,每个组都有一个ownerid,它指定谁拥有该组。每个组还有一个name,然后在用户表中,有一列group指定该人属于哪个组。 (请原谅烦人的结构,我没有创建它)。我试图找到group中的所有行,其中该组的ownerid没有group(在用户表中)设置为该组的name。如果这会有所帮助:

用户

|-----------------------| 
| id | username | group | 
|----|----------|-------| 
| 0 | Steve | night | 
| 1 | Sally | night | 
| 2 | Susan | sun | 
| 3 | David | xray | 
|-----------------------| 

集团

|---------------------| 
| ownerid | name  | 
|---------|-----------| 
| 1  | night  | 
| 3  | bravo  | 
| 2  | sun  | 
|---------------------| 

当SQL语句将返回组一行bravo因为Bravo的所有者没有他的组设置为喝彩。

+0

你的bash在SQL语句中在哪里? –

回答

1

这是一个连接回原来的表,然后将值的比较:

select g.* 
from group g join 
    user u 
    on g.ownerid = id 
where g.name <> u.group; 

如果值可以是NULL,则逻辑就需要考虑到这一点。

+0

这似乎有窍门,但由于某些原因,MySQL工作台告诉我输出行是只读的。 (我假设与分配组名g有关?)有什么办法可以解决这个问题吗? – user2249516

+0

@ user2249516。 。 。我不熟悉MySQL工作台会说输出是只读的所有原因。一个原因是桌子上缺少主键。 'group'是否有主键? –

+0

是的,它的确如此。我只需要复制输出,把它变成一个数组,然后从那里做,因为我从来没有想过为什么只读。感谢您的帮助,真的很感激它。 – user2249516

0
SELECT G.* 
FROM Group AS G 
WHERE G.Name NOT IN (SELECT DISTINCT U.Group FROM User AS U) 
1

的反连接是一种熟悉的模式:

SELECT g.* 
    FROM `Group` g 
    LEFT 
    JOIN `User` u 
    ON u.group = g.name 
    AND u.id = g.ownerid 
    WHERE u.id IS NULL 

让我们解开这一点。我们将开始返回来自Group的所有行。然后,我们将用组中的每行“匹配”来自用户的一行(或多行)。要被视为“匹配”,User.id必须与Group.ownerid匹配,并且User.group的值必须与Group.name匹配。

“诀窍”是消除我们找到匹配的所有行(这就是WHERE子句的作用),并且仅留下来自Group的那些没有匹配的行。

的另一种方法,以获得使用NOT的等效结果EXISTS谓词

SELECT g.* 
    FROM `Group` g 
WHERE NOT EXISTS 
     (SELECT 1 
      FROM `User` u 
      WHERE u.group = g.name 
      AND u.id = g.ownerid 
     ) 

这是使用一个相关子查询;它通常不如加入一样快。

请注意,如果您的组中有一行不在用户表中的ownerid值,那么这些结果可能会返回与Gordon Linoff的查询稍有不同的结果。