使用内部联接获取一个月的所有周数据

Posted

技术标签:

【中文标题】使用内部联接获取一个月的所有周数据【英文标题】:Getting all weeks data of a month using inner join 【发布时间】:2018-12-18 17:03:38 【问题描述】:

谁能更正这个查询:

select distinct 
    v.DriverName,t.KM_W1,t.KM_W2,t.KM_W3,t.KM_W4,t.KM_W5,(t.KM_W1+t.KM_W2+t.KM_W3+t.KM_W4+t.KM_W5) Total
from 
    (select 
         DriverName,
         SUM( case when TodayDate >= '01-07-2018' and TodayDate <= '07-07-2018' then PaidKM else 0 end) KM_W1,
         SUM( case when TodayDate >= '07-07-2018' and TodayDate <= '14-07-2018' then PaidKM else 0 end) KM_W2,
         SUM( case when TodayDate >= '14-07-2018' and TodayDate <= '21-07-2018' then PaidKM else 0 end) KM_W3,
         SUM( case when TodayDate >= '21-07-2018' and TodayDate <= '28-07-2018' then PaidKM else 0 end) KM_W4,
         SUM( case when TodayDate >= '28-07-2018' and TodayDate <= '31-07-2018' then PaidKM else 0 end) KM_W5
     from 
         Traveling
     group by 
         DriverName) t 
inner join
    Traveling v on t.DriverName = v.DriverName
where 
    TodayDate >= '01-07-2018' and TodayDate <= '31-07-2018'

上面的查询说明:我得到了所有星期的数据PaidKM 哪个司机在整整一个月里得到了。例如开始日期的月份是01-07-2018,结束日期是31-07-2018,涵盖整个月份#07。但是当我更改月份时,它总是给我相同的结果。

以上 GIF 的查询实现:我已经在 java 中实现了这个查询,当我从组合框中更改月份但后端查询始终给出所有记录而不是不同月份的结果。 p>

上图是数据库中的Traveling 表。

当我更改不同的月份时,我如何才能获得结果?以及我如何更正此查询以使其工作。

任何帮助将不胜感激!提前谢谢!

【问题讨论】:

我首先将日期格式更改为 YYYY-MM-DD -- ANSI 和 ISO 标准格式。这能解决你的问题吗? 不,我没试过。 你试过用strftime('%W',TodayDate)按周数分组 我想更改月份 # 而不是星期 #。 这将是日历表的另一个很好的用例。 【参考方案1】:

首先,这里有两个潜在的问题。您的查询中没有输入变量,所以我们必须先问这个。

您是否对语句末尾的WHERE 子句的参数传递进行了硬编码?

您是否对子查询中的SUM 语句的参数传入进行了硬编码?那些将一个月分成几周的人。

这些都可能是结果不变的原因。

这个查询的一个肯定问题是,您将重复计算表示一周开始/结束的日子的驾驶时间。

  ...SUM( case when TodayDate >= '01-07-2018' and TodayDate <= '07-07-2018' then PaidKM else 0 end) KM_W1,
    SUM( case when TodayDate >= '08-07-2018' and TodayDate <= '14-07-2018' then PaidKM else 0 end) KM_W2,...

您需要在下周开始前增加天数 我在这里通过将07-07-2018 更新为08-07-2018 来做到这一点

【讨论】:

您的问题的答案是否定的。然后我按照您的描述更改了日期,但结果仍然相同。 重叠日期是与您的原始问题不同的问题。这只是一个错误,必须先修复此报告,然后才能按照您希望的方式运行。【参考方案2】:

您的问题是比较是基于字符串而不是基于日期的。 的优先级高于月,月的优先级高于年。

例如31-01-1970 将被视为大于 01-01-2018,因为 31 大于 01

您应该考虑使用可直接排序/可比较的可识别日期格式,例如YYYY-MM-DD 处理/存储日期时。

您不妨考虑查看SQL As Understood By SQLite - Date And Time Functions - Time Strings

您可以使用

将日期转换为可排序/易于比较
substr(datevalue,7,4)||substr(datevalue,3,4)||substr(datevalue,1,2)

例如而不是:-

SUM( case when TodayDate >= '01-07-2018' and TodayDate <= '07-07-2018' then PaidKM else 0 end) KM_W1, ....

你可以使用:-

SUM( case when substr(TodayDate,7,4)||substr(Todaydate,3,4)||substr(Todaydate,1,2) >= '2018-07-01' and substr(TodayDate,7,4)||substr(Todaydate,3,4)||substr(Todaydate,1,2) <= '2018-07-07' then PaidKM else 0 end) KM_W1, ....

整个查询可能是:-

select distinct 
    v.DriverName,t.KM_W1,t.KM_W2,t.KM_W3,t.KM_W4,t.KM_W5,(t.KM_W1+t.KM_W2+t.KM_W3+t.KM_W4+t.KM_W5) Total
from 
    (select 
         DriverName,
         SUM( case when substr(TodayDate,7,4)||substr(Todaydate,3,4)||substr(Todaydate,1,2) >= '2018-07-01' and substr(TodayDate,7,4)||substr(Todaydate,3,4)||substr(Todaydate,1,2) <= '2018-07-07' then PaidKM else 0 end) KM_W1,
         SUM( case when substr(TodayDate,7,4)||substr(Todaydate,3,4)||substr(Todaydate,1,2) >= '2018-07-08' and substr(TodayDate,7,4)||substr(Todaydate,3,4)||substr(Todaydate,1,2) <= '2018-07-14' then PaidKM else 0 end) KM_W2,
         SUM( case when substr(TodayDate,7,4)||substr(Todaydate,3,4)||substr(Todaydate,1,2) >= '2018-07-15' and substr(TodayDate,7,4)||substr(Todaydate,3,4)||substr(Todaydate,1,2) <= '2018-07-21' then PaidKM else 0 end) KM_W3,
         SUM( case when substr(TodayDate,7,4)||substr(Todaydate,3,4)||substr(Todaydate,1,2) >= '2018-07-22' and substr(TodayDate,7,4)||substr(Todaydate,3,4)||substr(Todaydate,1,2) <= '2018-07-28' then PaidKM else 0 end) KM_W4,
         SUM( case when substr(TodayDate,7,4)||substr(Todaydate,3,4)||substr(Todaydate,1,2) >= '2018-07-29' and substr(TodayDate,7,4)||substr(Todaydate,3,4)||substr(Todaydate,1,2) <= '2018-07-31' then PaidKM else 0 end) KM_W5
     from 
         Traveling
     group by 
         DriverName) t 
inner join
    Traveling v on t.DriverName = v.DriverName
where 
    substr(TodayDate,7,4)||substr(Todaydate,3,4)||substr(Todaydate,1,2) >= '2018-07-01' and substr(TodayDate,7,4)||substr(Todaydate,3,4)||substr(Todaydate,1,2) <= '2018-07-31'
注意以上为原理代码,未经测试,可能存在一些错误。

【讨论】:

非常好的回答谢谢你拯救了我的 50 赏金声誉.. 再次感谢。 我刚刚使用了 YYYY-MM-DD 格式,它解决了。

以上是关于使用内部联接获取一个月的所有周数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在employee_id上 进行内部联接时获取每个唯一员工的销售总额

如何使用内部联接创建触发器

如何从内部联接查询之一中获取总数?

使用 NamedQuery 进行内部联接?

使用spark数据帧/数据集/ RDD使用内部联接进行更新

如何从当前日期 PHP 获取最近 7 周、7 个月的日期范围?