假设我有以下表格:
Batch Items
---+----- ---+----------+--------
id | size id | batch_id | quality
---+----- ---+----------+--------
1 | 10 1 | 1 | 9
2 | 2 2 | 1 | 10
3 | 2 | 1
4 | 2 | 2
5 | 2 | 1
6 | 2 | 9
我有批次的物品。它们是按批量batch.size
批量发送的。如果一个项目的质量是< = 3。
我想知道发送的最后一批产品中已损坏的商品数量:
batch_id | broken_item_count
---------+---------------------
1 | 0
2 | 2 (and not 3)
我的想法如下:
SELECT batch.id as batch_id, COUNT(broken_items.*) as broken_item_count
FROM batch
INNER JOIN (
SELECT id
FROM items
WHERE items.quality <= 3
ORDER BY items.id asc
LIMIT batch.size -- invalid reference to FROM-clause entry for table "batch"
) broken_items ON broken_items.batch_id = batch.id
(我会ORDER BY
items.shipped_at
。但为了简单起见,我按items.id
订购
但是这个查询向我显示了我作为评论的错误。
如何根据每行不同的batch.size
来限制已加入项目的数量?
还有其他方法可以实现我的目标吗?
答案 0 :(得分:1)
select
b.id as batch_id,
count(quality <= 3 or null) as broken_item_count
from
batch b
inner join (
select
id, quality, batch_id,
row_number() over (partition by batch_id order by id) as rn
from items
) i on i.batch_id = b.id
where rn <= b.size
group by b.id
order by b.id
答案 1 :(得分:1)
SELECT b.id AS batch_id
, count(i.quality < 4 OR NULL) AS broken_item_count
FROM batch b
LEFT JOIN (
SELECT batch_id, quality
, row_number() OVER (PARTITION BY batch_id ORDER BY id DESC) AS rn
FROM items
) i ON i.batch_id = b.id
AND i.rn <= b.size
GROUP BY 1
ORDER BY 1;
SQL Fiddle with added examples.
这很像@Clodoaldos's answer,但有一些不同之处。最重要的是:
broken items in the last batches sent
,因此我们必须ORDER BY id
DESC
LEFT JOIN
而不是普通JOIN
,否则将排除这些批次。i.rn <= b.size
需要从WHERE
子句移到JOIN
子句。答案 2 :(得分:0)
据我所知,缺陷物品的数量不能大于批量大小。
编辑:在阅读您的评论后,我认为使用RANK()
功能,然后按等级和大小加入应该适合您。以下查询尝试使用。
SELECT b.id,
SUM(CASE WHEN i1.quality <= 3 THEN 1 ELSE 0END) as broken_item_count
FROM BATCH as b
LEFT JOIN (SELECT i.id, i.batch_id, i.quality,
RANK() OVER(PARTITION BY i.batch_id ORDER BY i.id) as RANK
FROM ITEMS as i) as i1 ON b.id = i1.batch_id AND i1.RANK <= b.size
GROUP BY b.id
EDIT2 :使用LEFT JOIN
更新了查询,以涵盖某些batch
中没有样本的情况。