加入子查询,计数和分组

时间:2009-09-16 08:58:20

标签: mysql sql database database-design

我有三个表,每个表都是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...

现在我想要第二个事实,即每辆车所有车轮都有多少生锈和干净的螺丝,而不需要知道每个车轮的每个特定数量。 所以基本上现在我只是把wheel BY放在wheel_id上,就像这样:

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

问题是,我需要在一个查询中同时使用它们,因为否则我会进行大量的排序和重新排序。

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

这是怎么做到的?

我会对一个非常具体的答案感到高兴,因为我不是一个真正的SQL向导。

编辑:我正在开发一个ORM,所以funky认为如下(将col值隐藏到某个常量)不能轻易地在那里完成。我必须让这个解决方案在那里工作,所以JOIN / subquery / UNIONs没有时髦的解决方法会很棒。

2 个答案:

答案 0 :(得分: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
...

答案 1 :(得分: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