当我在 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
.
即使你删除了单引号,你也不会得到你想要的结果,因为你会得到 id
s.
的总和
但是如果你使用:
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';
请注意,这会直接比较 date
与 where
子句中的有效日期。
我正在尝试查找 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
.
即使你删除了单引号,你也不会得到你想要的结果,因为你会得到 id
s.
的总和
但是如果你使用:
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';
请注意,这会直接比较 date
与 where
子句中的有效日期。