【问题标题】:SQL query not returning the things I wantSQL 查询没有返回我想要的东西
【发布时间】:2021-04-07 09:48:44
【问题描述】:

我很困惑为什么我的查询没有返回我想要的东西。有人可以帮我解决这个问题吗?

表格:

查询(CTE):

WITH cancel AS(
SELECT t.Request_at AS day, IFNULL(COUNT(t.Status),0) AS cancelled
FROM Trips t
LEFT JOIN Users u
ON t.Client_Id = u.Users_Id
WHERE (t.Status = "cancelled_by_driver" or t.Status = "cancelled_by_client")
AND t.Request_at BETWEEN "2013-10-01" AND "2013-10-03"
AND u.Banned = "No"
GROUP BY t.Request_at)

所以我在这里想要的是让我上面的 cte 返回 2013 年 10 月 1 日至 2013 年 10 月 3 日期间未被禁止的用户或司机取消的旅行次数。我的查询返回正确的数字对于已取消但未在未取消的日期返回“0”的日期。我不知道为什么结果是这样的,因为我已经使用了 IFNULL 并且已经使用了左连接。

【问题讨论】:

  • 请放。您在问题中的查询作为文本。
  • 嗨,Gordan,我只是将它们作为文本输入。

标签: mysql sql datetime pivot aggregate-functions


【解决方案1】:

where 子句会在您有机会将其包含在结果集中之前驱逐没有取消驱动器的日期。

如果您在表格中有所有可用日期(无论状态如何),您只需在聚合中移动条件:

select t.request_at, 
    sum(t.status in ('cancelled_by_driver', 'cancelled_by_client')) as cnt_cancelled
from trips t
inner join users u on u.user_id = t.client_id
where u.banned = 'No' and t.request_at between '2013-10-01' and '2013-10-03'
group by t.request_at

更通用的方法是使用日历表来处理日期,然后将表带上left join。如果您没有这样的表,您可以使用递归查询动态生成它(在 MySQL 8.0 中可用):

with recursive cal as (
    select '2013-10-01' as dt
    union all
    select dt + interval 1 day from cal where dt < '2013-10-03'
)
select c.dt, count(t.id) as cnt_cancelled
from cal c
left join trips t on t.request_at = c.dt and t.status in ('cancelled_by_driver', 'cancelled_by_client')
left join users u on u.user_id = t.client_id and u.banned = 'No'
group by c.dt

【讨论】:

  • 嗨!所以这意味着我的查询将在 IFNULL 之前运行 where 部分?
  • 这是否意味着我不能在这里使用 COUNT ?
  • @EricsonLi:where 子句过滤数据集。在您的原始查询中,这会消除没有取消请求的日期。
  • 非常感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2011-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-09
  • 2021-12-26
  • 2023-01-29
  • 1970-01-01
相关资源
最近更新 更多