2016-08-13 223 views
0

我有两个表;一个带有联系信息,另一个带有一个组列表。例如:SQL查询其中两列的组合是唯一的(带有子查询)

clients 
+-------------+---------------+-------------+------------+ 
| client_id | client_name | group1_id | group2_id | 
+-------------+---------------+-------------+------------+ 
| 283   | John Smith | 1   | null  | 
| 284   | Jane Smith | 1   | 2   | 
| 285   | Tim Johnson | 1   | null  | 
| 286   | Peter Guy  | null  | null  | 
+-------------+---------------+-------------+------------+ 

groups 
+------------+----------------+ 
| group_id | group_name | 
+------------+----------------+ 
| 1   | Smith Group | 
| 2   | Johnson Group | 
+------------+----------------+ 

如果不是不言而喻,group1_id和group2_id是组表中的外键。

我需要编写一个查询来选择客户端名称和组名称。如果客户是两个组的成员(如Jane Smith),他们应该在输出中出现两次。理想情况下,每行应输出组名称,然后在括号中输入客户名称,所有结果应按字母顺序排序。所以对于上面的表输出应该是:

John Smith (Jane Smith) 
Johnson Group (Jane Smith) 
Johnson Group (Tim Johnson) 
Smith Group (John Smith) 

这是可能使用单个SQL查询吗?

我正在使用MySQL。目前我正处于项目的计划阶段,所以如果我需要更改数据库模式以更好地支持我的工作。

在此先感谢。

+2

如果客户是3个组的成员,该怎么办? – Strawberry

+0

@Strawberry我们做出了不支持三组的设计决定。一个客户分两个组是很少见的。他们分成三组并不是不可能的,但实际上它可能永远不会发生。在我们的情况下,如果组3没有在输出中列出,那么它不是世界末日。 – Gechurch

回答

2

是的,这可以使用joininor

select c.client_name, g.group_name 
from clients c 
    join groups g on g.group_id in (c.group1_id, c.group2_id) 

不过,我会建议寻找到database normalization。改变你的表格结构以包括名为ClientGroup的第三个表格会更好地用作联结表格。然后,你最终会是这样的:

clients (client_id, client_name) 
groups (group_id, group_name) 
clientgroup (client_id, group_id) 

然后你可以只join表再次合作:

select c.client_name, g.group_name 
from clients c 
    join clientgroup cg on c.client_id = cg.client_id 
    join groups g on cg.group_id = c.group_id 
0

如果你想要两个行时客户匹配两次,然后使用or

select c.client_name, g.group_name 
from clients c join 
    groups g 
    on g.group_id = c.group1_id or g.group_id = c.group2_id; 

这将结果格式化为两列,而不是将组名称放在括号中的字符串。

0

谢谢sgeddes和Gordon的快速和有用的答案。我想我需要一个连接,但是无法使语法正确(我之前没有使用连接)。看到其他人给出答案后,最终结果非常明显!

括号中为分类和客户的名字,最终的查询是:

SELECT client_id, CONCAT(g.group_name, " (", c.client_name, ")") new_col 
FROM clients c 
    JOIN groups g on g.group_id IN (c.group1_id, c.group2_id) 
ORDER BY g.group_id, c.client_name ASC 

我是第一次海报和不能看到的方式来奖励一个答案。我是否错过了一些东西,还是只有提供赏金才能获奖的问题?