当我在 sqlite3 中使用 SUM(CASE WHEN .... THEN "column_name") 时,我得到了意想不到的结果

I'm getting unexpected results when I use SUM(CASE WHEN .... THEN "column_name") in sqlite3

我正在尝试查找 4 月份收到的订单数量。我有 3 个订单,但我的查询得到结果 0。可能是什么问题?

这是table:

id | first   | middle | last    | product_name  | numberOut | Date
1 | Muhammad | Sameer | Khan    | Macbook       | 1         | 2020-04-01
2 | Chand    | Shah   | Khurram | Dell Optiplex | 1         | 2020-04-02
3 | Sultan   |        | Chohan  | HP EliteBook  | 1         | 2020-03-31
4 | Express  | Eva    | Plant   | Dell Optiplex | 1         | 2020-03-11
5 | Rana     | Faryad | Ali     | HP EliteBook  | 1         | 2020-04-02

这是查询:

SELECT SUM(CASE WHEN strftime('%m', oDate) = '04' THEN 'id' END) FROM orders;

您的查询有问题。您不需要执行该聚合操作。

SELECT COUNT(*) from table_name WHERE strftime('%m', Date) = '04';
SELECT SUM(CASE WHEN strftime('%m', oDate) = '04' THEN 1 ELSE 0 END) FROM orders; 

如果您需要使用 SUM

我会使用显式日期比较而不是日期函数 - 这使得查询 SARGeable,即它可能有益于现有索引。

最有效的方法,在 where 子句中使用过滤器:

select count(*) cnt
from orders 
where oDate >= '2020-04-01' and oDate < '2020-05-01'

或者,如果您想要 0 结果,即使在 4 月没有订单时,您也可以进行条件聚合,如您最初预期的那样:

select sum(case when oDate >= '2020-04-01' and oDate < '2020-05-01' then 1 else 0 end) cnt
from orders

你的代码问题是这样的:

THEN 'id'

你正在使用聚合函数 SUM() 并且你对像 'id' 这样的字符串文字求和,它被隐式转换为 0 (因为它不能转换为数字) 所以结果是 0.
即使你删除了单引号,你也不会得到你想要的结果,因为你会得到 ids.
的总和 但是如果你使用:

THEN 1 ELSE 0

那么你会得到正确的结果。
但是使用 SQLite 你可以写得更简单:

SELECT SUM(strftime('%m', oDate) = '04') FROM orders;

没有 CASE 表达式。
或者因为您只想计算订单数,那么 COUNT() 就可以了:

SELECT COUNT(*) FROM orders WHERE strftime('%m', oDate) = '04';

编辑。
如果你想计算所有月份的订单,然后按月分组:

SELECT strftime('%Y-%m', oDate) AS month, 
       COUNT(*) AS number_of_orders
FROM orders 
GROUP BY month;

如果你想要所有个四月,那么你可以只看月份。我会推荐:

select count(*)
from orders o
where o.date >= '2020-04-01' and o.date < '2020-05-01';

请注意,这会直接比较 datewhere 子句中的有效日期。