简体   繁体   English

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

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

I am trying to find the number of orders I got in the month of April.我试图找到我在 4 月份收到的订单数量。 I have 3 orders but my query gets the result 0. What could be the problem?我有 3 个订单,但我的查询结果为 0。可能是什么问题?

Here's the 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

And here's the query:这是查询:

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

The problem with your code is this:您的代码的问题是:

THEN 'id'

You are using the aggregate function SUM() and you sum over a string literal like 'id' which is implicitly converted to 0 (because it can't be converted to a number) so the result is 0 .您正在使用聚合函数SUM()并对像'id'这样的字符串文字求和,该字符串被隐式转换为0 (因为它无法转换为数字),因此结果为0
Even if you remove the single quotes you will not get the result that you want because you will get the sum of the id s.即使您删除单引号,您也不会得到您想要的结果,因为您将得到id的总和。
But if you used:但如果你使用:

THEN 1 ELSE 0

then you would get the correct result.那么你会得到正确的结果。
But with SQLite you can write it simpler:但是使用 SQLite 你可以写得更简单:

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

without the CASE expression.没有CASE表达式。
Or since you just want to count the orders then COUNT() will do it:或者因为您只想计算订单,然后COUNT()会这样做:

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

Edit.编辑。
If you want to count the orders for all the months then group by month:如果要计算所有月份的订单,请按月分组:

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

If you want all Aprils, then you can just look at the month.如果你想要所有的四月,那么你可以只看月份。 I would recommend:我会推荐:

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

Note that this does direct comparisons of date to a valid dates in the where clause.请注意,这会直接将datewhere子句中的有效日期进行比较。

There is a problem with your query.您的查询有问题。 You do not need to do that aggregation operation.您不需要执行该聚合操作。

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

I would use explicit date comparisons rather than date functions - this makes the query SARGeable, ie it may benefit an existing index.我将使用显式日期比较而不是日期函数 - 这使得查询 SARGeable,即它可能有益于现有索引。

The most efficient approach, with a filter in the where clause:最有效的方法,在where子句中使用过滤器:

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

Alternatively, if you want a result of 0 even when there are no orders in April you can do conditional aggregation, as you originally intended:或者,如果即使 4 月份没有订单,您也希望结果为0 ,您可以按照您最初的意图进行条件聚合:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM