尝试在MySQL中的单个查询中选择多个计数

时间:2014-03-28 15:22:26

标签: sql database select count nested

我有一张商店订单表。这些订单有一个布尔属性,表明它们是否需要交付给客户。还有另一个表格说明订单是否完整。

我想计算已交付发票的数量,剩余发票,然后只计算已完成(已付款)的发票总数。

这是我到目前为止所尝试的:

SELECT 
    COUNT(SELECT INVOICE_ID FROM INVOICE_LINE AS I, INVOICE_COMPLETE AS IC WHERE TO_DELIVER = 1 AND I.INVOICE_ID = IC.INVOICE_ID AND IC.COMPLETE = 1) AS DELIVERED, 
    COUNT(SELECT INVOICE_ID FROM INVOICE_LINE AS I, INVOICE_COMPLETE AS IC WHERE TO_DELIVER = 0 AND I.INVOICE_ID = IC.INVOICE_ID AND IC.COMPLETE = 1) AS REMAINING,
    COUNT(INVOICE_ID) AS TOTAL
FROM INVOICE_LINE AS I, INVOICE_COMPLETE AS IC
WHERE TO_DELIVER = 1
AND I.INVOICE_ID = IC.INVOICE_ID

抛出以下语法错误:

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT INVOICE_ID FROM INVOICE_LINE AS I, INVOICE_COMPLETE AS IC WHERE TO_DELIVE' at line 2

我在哪里错了。这是我第一次尝试嵌套这样的语句。

3 个答案:

答案 0 :(得分:0)

有一种更简单的方法:外连接invoice_complete和计数匹配:

SELECT 
  COUNT(IC.INVOICE_ID) AS DELIVERED, 
  COUNT(*) - COUNT(IC.INVOICE_ID) AS REMAINING,
  COUNT(*) AS TOTAL
FROM INVOICE_LINE AS I
LEFT JOIN INVOICE_COMPLETE AS IC ON I.INVOICE_ID = IC.INVOICE_ID AND IC.COMPLETE = 1
WHERE TO_DELIVER = 1;
编辑:嗯,我还应该解释你做错了什么:计数需要*,列或表达式。对于列或表达式,它将计算非空出现,因为*它计算记录。你可以使用select语句作为表达式,但是它必须有额外的括号,并且必须使用from子句完成:select count((select x from y)) from ...

最后一个建议:使用显式连接语法(INNER JOIN x ON ...,LEFT JOIN y ON ...等),而不是仅使用逗号列出表。这增强了可读性并有助于避免错误。

答案 1 :(得分:0)

你可以像下面那样写:

declare @toDeliver as int = (SELECT COUNT(INVOICE_ID) FROM INVOICE_LINE AS I, INVOICE_COMPLETE      AS IC WHERE TO_DELIVER = 0 AND I.INVOICE_ID = IC.INVOICE_ID AND IC.COMPLETE = 1)
declare @deliverd as int = (SELECT COUNT(INVOICE_ID) FROM INVOICE_LINE AS I, INVOICE_COMPLETE AS    IC WHERE TO_DELIVER = 1 AND I.INVOICE_ID = IC.INVOICE_ID AND IC.COMPLETE = 1) 
SELECT 
    @toDeliver as REMAINING, 
    @delivered as DELIVERED,
    @toDeliver + @delivered AS TOTAL

答案 2 :(得分:0)

其他答案可以让您更好地了解如何执行此操作。

但错误似乎来自count函数内的子选择。

此更改可能对您有用:

    SELECT 
    (SELECT COUNT(INVOICE_ID) FROM INVOICE_LINE AS I, INVOICE_COMPLETE AS IC WHERE TO_DELIVER = 1 AND I.INVOICE_ID = IC.INVOICE_ID AND IC.COMPLETE = 1) AS DELIVERED, 
    (SELECT COUNT(INVOICE_ID) FROM INVOICE_LINE AS I, INVOICE_COMPLETE AS IC WHERE TO_DELIVER = 0 AND I.INVOICE_ID = IC.INVOICE_ID AND IC.COMPLETE = 1) AS REMAINING,
    COUNT(INVOICE_ID) AS TOTAL
FROM INVOICE_LINE AS I, INVOICE_COMPLETE AS IC
WHERE TO_DELIVER = 1
AND I.INVOICE_ID = IC.INVOICE_ID

这只会移动子选择内的计数。

或在子选择周围添加括号:

SELECT 
    COUNT((SELECT INVOICE_ID FROM INVOICE_LINE AS I, INVOICE_COMPLETE AS IC WHERE TO_DELIVER = 1 AND I.INVOICE_ID = IC.INVOICE_ID AND IC.COMPLETE = 1)) AS DELIVERED, 
    COUNT((SELECT INVOICE_ID FROM INVOICE_LINE AS I, INVOICE_COMPLETE AS IC WHERE TO_DELIVER = 0 AND I.INVOICE_ID = IC.INVOICE_ID AND IC.COMPLETE = 1)) AS REMAINING,
    COUNT(INVOICE_ID) AS TOTAL
FROM INVOICE_LINE AS I, INVOICE_COMPLETE AS IC
WHERE TO_DELIVER = 1
AND I.INVOICE_ID = IC.INVOICE_ID
;