Sql Count Where Groupby子查询

时间:2016-02-21 10:56:18

标签: sql sqlite

嘿,我有这个问题,

SELECT item_type.id, item_type.item_type, 
    (SELECT COUNT(*) FROM item WHERE item.sale_transaction_id IS NULL) as stock_qty,
    (SELECT COUNT(*) FROM item WHERE item.sale_transaction_id IS NOT NULL) as sold_qty
FROM item
JOIN item_type ON item.item_type_id = item_type.id
GROUP BY item.item_type_id

这给了我一个结果:

| id | item_type | stock_qty | sold_qty|
----------------------------------------
| 1  | Book      | 12        | 12      |
| 2  | Pencil    | 12        | 12      |
| ........... # etc

但是这不能按预期工作,我需要像这样做才能使它工作:

SELECT item_type.id, item_type.item_type, 
    COUNT(item.purchase_transaction_id) - COUNT(item.sale_transaction_id) as stock_qty,
    COUNT(item.sale_transaction_id) as sold_qty
FROM item
JOIN item_type ON item.item_type_id = item_type.id
GROUP BY item.item_type_id

结果就是我想要的,这是正确/预期的输出:

| id | item_type | stock_qty | sold_qty|
----------------------------------------
| 1  | Book      | 1         | 0       |
| 2  | Pencil    | 0         | 5       |
| ........... # etc

在我的表格结构中,sale_transaction_id的每个项目都标记为已售出。 我的问题是为什么第一个没有按预期工作?我如何让它作为第二个工作?实际上是否可以使用子查询进行此类查询?

3 个答案:

答案 0 :(得分:2)

SELECT item_type.id, item_type.item_type, 
SUM(case when item.sale_transaction_id IS NULL then 1 else 0 end) as stock_qty,
SUM(case when item.sale_transaction_id IS NOT NULL then 1 else 0  end) as sold_qty
FROM item
JOIN item_type ON item.item_type_id = item_type.id
GROUP BY item_type.id, item_type.item_type

这是你需要的吗?

答案 1 :(得分:1)

您需要将相关性添加到子查询中:

SELECT item_type.id, item_type.item_type, 
    (SELECT COUNT(item.purchase_transaction_id) - COUNT(item.sale_transaction_id)
     FROM item 
     WHERE item.item_type_id = i.item_type_id) as stock_qty,
    (SELECT COUNT(item.sale_transaction_id) 
     FROM item 
     WHERE item.item_type_id = i.item_type_id ) as sold_qty
FROM item AS i
JOIN item_type ON i.item_type_id = item_type.id
GROUP BY i.item_type_id

子查询现在是相关的:它们是针对外部查询的每个item_type_id执行的,并且每次都返回此精确值的结果。

但这似乎是一种矫枉过正,因为你可以在外部查询中得到相同的结果,就像你在问题的第二个查询中那样。

答案 2 :(得分:1)

从" item_type&#34开始;表,而不是" item"表并使用左连接,否则如果没有类型的项目,则永远不会在查询结果中获得一行。

SELECT
    item_type.id,
    item_type.item_type,
    SUM(CASE WHEN item.id IS NOT NULL AND item.sale_transaction_id IS NULL THEN 1 ELSE 0 END) AS stock_qty,
    SUM(CASE WHEN item.id IS NOT NULL AND item.sale_transaction_id IS NOT NULL THEN 1 ELSE 0 END) AS sold_qty
FROM
    item_type
LEFT JOIN
    item
ON
    item.item_type_id = item_type.id
GROUP BY
    item_type.id, item_type.item_type

避免使用子选择。您使用的每个子选择都将针对每一行执行,这将大大降低性能。您可以对两个查询(子选择和加入版本)运行解释,您将看到我的意思

如果您发布初始表的示例数据,将会很有帮助。