2013-12-20 53 views
2

我试图解决这个SQL问题,我有一打不同的彩球和几个盒子。现在,我试图编写一个SQL查询,输出每个框中球的颜色。所以,如果在方框A,B和C中存在绿球,但蓝球和红球在3个方框中只有1或2个,我应该只输出绿色。SQL:只输出每个框中的球的颜色/颜色

我有三个表:

ID | 
====| 
A | 
B | 
C | 

Number | boxid | colorid | 
=======|=======|=========| 
1  |A  | Green | 
2  |A  | Red  | 
3  |A  | Blue | 
4  |B  | Green | 
5  |B  | Red  | 
6  |NULL | Blue | 
7  |C  | Green | 
8  |NULL | Red  | 
9  |NULL | Blue | 
10  |NULL | Green | 
11  |NULL | Red  | 
12  |NULL | Blue | 

NULL意味着他们没有任何内部的箱子

颜色

Name | 
======| 
Blue | 
Red | 
Green | 

现在,起初我以为我可以使用此代码解决这个问题:

SELECT colorid 
FROM Ball 
GROUP BY colorid 
HAVING COUNT(colorid) = (SELECT COUNT(*) FROM Box) 
OR COUNT(colorid) > (SELECT COUNT(*) FROM Box) 

但后来我意识到,一旦你给一个值,有NULL上boxid它的行我也会输出这些颜色,因为我的SQL查询没有考虑到彩球必须位于所有三个不同的盒子中,只是所有三个彩球都放在任何盒子里。

我难以理解如何改变我的查询,以便它只计数球是否在另一个盒子中。请帮忙。

回答

2

假设我们知道,不同的箱子的数量是3:

SELECT colorId 
    FROM Ball 
    WHERE boxid IS NOT NULL 
GROUP BY colorId 
    HAVING COUNT (DISTINCT boxid) = 3 

否则

SELECT colorId 
    FROM Ball 
    WHERE boxid IS NOT NULL 
GROUP BY colorId 
    HAVING COUNT (DISTINCT boxid) = SELECT COUNT (DISTINCT ID) FROM Box 

如果球能在从Box三个不同的盒子,那么我们需要一个子查询只计算我们关心的盒子里的球。

SELECT colorId 
    FROM Ball 
    WHERE EXISTS(SELECT 1 FROM Box WHERE ID = boxid) 
GROUP BY colorId 
    HAVING COUNT (DISTINCT boxid) = SELECT COUNT (DISTINCT ID) FROM Box 
+0

我不认为WHERE colorid IS NOT NULL,我可以使用色彩,因为这些值是可以改变的 – user3124096

+0

你是什么意思?查询代表某个时间点db的状态,因此它们不能“更改” – Sklivvz

+0

我的意思是如果有人更新表格Ball以便每个球在boxid中都有一个值,那么该查询将不起作用。 – user3124096

0

您可以首先创建一个交叉连接的可能组合和内部连接,按颜色分组。

0

使用内部连接...发现,在所有3盒

SELECT DISTINCT 
    colorID 
FROM 
    Ball 

    INNER JOIN (SELECT boxID, colorID FROM Ball WHERE boxID = 'A') A 
    ON Ball.colorID = A.colorID 

    INNER JOIN (SELECT boxID, colorID FROM Ball WHERE boxID = 'B') B 
    ON Ball.colorID = B.colorID 

    INNER JOIN (SELECT boxID, colorID FROM Ball WHERE boxID = 'C') C 
    ON Ball.colorID = C.colorID 
+0

是否可以修改它,使其即使我插入一个新的ID到表框(意味着我添加另一个框),它将工作?似乎必须为每个Box添加一个INNER JOIN。 – user3124096