2009-09-16 103 views
0

我有三个表,每个表分别是1:n。 table1中的条目在table2中有n个条目,依此类推。让我们称他们为汽车,轮子和螺丝钉来说明。 螺丝可以清洁(1)或生锈(2)。我一起加入他们,因为我想统计两件事情。首先,我想要有行,告诉我每个车有多少个好/坏的螺丝。所以基本上我越来越:加入子查询,计数和分组

car_id wheel_id screw_state count(screws) 
    1   1   1   3 
    1   1   2   7 
    1   2   1   5 
    1   2   2   3 
    2   1   1   1 
       ... and so on... 

现在我想第二个事实,我即有多少生锈和清洁的螺丝有每车所有车轮,而不需要知道每个车轮的每一个具体的数字。 所以基本上我现在只留下断GROUP BY超过wheel_id,像这样:

car_id screw_state count(screws) 
    1   1    8 
    1   2   10 
    2   1    1 
       ... and so on... 

的事情是,我需要他们两个在一个单一的查询,因为否则我有大量的排序和重新安排去做。

我相信第二个更容易计算每个汽车的总螺丝数量应该作为子查询来完成,但是我可以使用子查询轻松加入第一个更大的查询吗?

这是如何完成的?

我会很高兴一个相当具体的答案,因为我不是一个真正的SQL向导。

编辑:我正在研究一个ORM,所以像下面这样怪异的想法(将col值篡改为某个常量)不能轻易在那里完成。我必须得到这个解决方案在那里工作,所以JOIN/subquery/UNIONs没有时髦的解决方法将是伟大的。

回答

1
SELECT car_id, wheel_id, screw_state, count(screws) 
    FROM cars C, wheels W, screws S 
WHERE W.car_id = C.car_id 
    AND S.wheel_id = W.wheel_id 
GROUP BY car_id, wheel_id, screw_state 
UNION ALL 
SELECT car_id, -1 AS wheel_id, screw_state, count(screws) 
    FROM cars C, wheels W, screws S 
WHERE W.car_id = C.car_id 
    AND S.wheel_id = W.wheel_id 
GROUP BY car_id, screw_state 
ORDER BY car_id 

您可以UNION 2查询,每辆车所有车轮的第二个查询,这就是为什么wheel_id = -1。

结果:

car_id wheel_id screw_state count(screws) 
     1   1   1   3 
     1   1   2   7 
     1   2   1   5 
     1   2   2   3 
     1   -1   1   8 
     1   -1   2   10 
     2   1   1   1 
     2   -1   1   1 
... 
+0

现在来测试的,可悲的是我的MySQL服务器犯规一样,“-1 wheel_id”语法。我试图写wheel_id = -1,它似乎工作,除了在输出的事实,wheel_id出来的总计数为0,而不是-1,但其余似乎工作。 – Tom 2009-09-16 09:37:10

+0

我使用MS SQL服务器语法,可能对于你必须放置的MySQL:-1 as wheel_id。我在我的答案中解决了它。 – manji 2009-09-16 09:42:21

+0

SELECT car_id,-1,screw_state,count(螺丝)适用于我 – Tom 2009-09-16 10:23:40

1

快速搜索说,MySQL支持GROUPING SETS。这是该功能一个很好的候选人:

SELECT car_id, wheel_id, screw_state, count(screws) 
FROM cars C 
JOIN wheels W ON W.car_id = C.car_id 
JOIN screws S ON S.wheel_id = W.wheel_id 
GROUP BY GROUPING SETS (
    (car_id, screw_state, wheel_id), 
    (car_id, screw_state) 
) 
ORDER BY car_id, wheel_id, screw_state 
+1

好主意,但MySQL不支持分组集。甚至PostgreSQL最近也获得了这个功能。 – 2009-09-17 11:32:23

+0

@Seun:谢谢你纠正我!我应该检查MySQL手册,而不仅仅是谷歌搜索和信任随机文章。[1] [1] http://www.informit.com/articles/article.aspx?p=664143&seqNum=10&rll=1 – 2009-09-17 22:03:55

+0

没有问题,如果这个工作,你的答案应该是我的第一选择,它的更紧凑和优雅。 – Tom 2009-09-17 22:08:23