我不知道如何用 Ruby 编写它,但从 SQL 的角度来看,我觉得您需要一个子查询来按订单聚合交付数量。
类似的东西(我直接输入 SO - 请原谅拼写错误或愚蠢的语法错误):
SELECT orders.* FROM orders
LEFT OUTER JOIN (SELECT COUNT(*) AS C, deliveries.order_id AS ID
FROM deliveries
GROUP BY deliveries.order_id) AS S
ON orders.id = S.ID
WHERE S.C < orders.number_of_deliveries_paid_for
OR (deliveries.id IS NULL AND orders.number_of_deliveries_paid_for > 0);
编辑:事实上,这使用起来要简单得多ORDER BY ... HAVING
:
SELECT *, count(*) AS C FROM orders
LEFT OUTER JOIN deliveries
ON deliveries.order_id = orders.id
GROUP BY orders.id
HAVING C < orders.number_of_deliveries_paid_for
OR (deliveries.id IS NULL AND orders.number_of_deliveries_paid_for > 0);
对于好奇的人,这是我的测试用例:
mysql> select * from orders;
+------+---------+-------------------------------+
| id | name | number_of_deliveries_paid_for |
+------+---------+-------------------------------+
| 1 | Order 1 | 0 |
| 2 | Order 2 | 2 |
| 3 | Order 3 | 3 |
+------+---------+-------------------------------+
3 rows in set (0.00 sec)
mysql> select * from deliveries;
+----+----------+
| id | order_id |
+----+----------+
| 1 | 2 |
| 2 | 2 |
| 3 | 3 |
| 4 | 3 |
+----+----------+
4 rows in set (0.00 sec)
mysql> select * from orders JOIN deliveries ON deliveries.order_id = orders.id -> ;
+------+---------+-------------------------------+----+----------+
| id | name | number_of_deliveries_paid_for | id | order_id |
+------+---------+-------------------------------+----+----------+
| 2 | Order 2 | 2 | 1 | 2 |
| 2 | Order 2 | 2 | 2 | 2 |
| 3 | Order 3 | 3 | 3 | 3 |
| 3 | Order 3 | 3 | 4 | 3 |
+------+---------+-------------------------------+----+----------+
4 rows in set (0.00 sec)
作为旁注,请参阅 和 之间的JOIN
区别LEFT JOIN
:
mysql> select *, COUNT(*) from orders LEFT JOIN deliveries ON deliveries.order_id = orders.id group by orders.id;
+------+---------+-------------------------------+------+----------+----------+
| id | name | number_of_deliveries_paid_for | id | order_id | COUNT(*) |
+------+---------+-------------------------------+------+----------+----------+
| 1 | Order 1 | 0 | NULL | NULL | 1 |
| 2 | Order 2 | 2 | 1 | 2 | 2 |
| 3 | Order 3 | 3 | 3 | 3 | 2 |
+------+---------+-------------------------------+------+----------+----------+
3 rows in set (0.00 sec)
mysql> select *, COUNT(*) from orders JOIN deliveries ON deliveries.order_id = orders.id group by orders.id;
+------+---------+-------------------------------+----+----------+----------+
| id | name | number_of_deliveries_paid_for | id | order_id | COUNT(*) |
+------+---------+-------------------------------+----+----------+----------+
| 2 | Order 2 | 2 | 1 | 2 | 2 |
| 3 | Order 3 | 3 | 3 | 3 | 2 |
+------+---------+-------------------------------+----+----------+----------+
2 rows in set (0.01 sec)