基于当月的动态 SQL 查询
Posted
技术标签:
【中文标题】基于当月的动态 SQL 查询【英文标题】:Dynamic SQL query which is based on current month 【发布时间】:2018-03-02 10:10:17 【问题描述】:下面是一个 SQL 代码,它从每月数据摘要的联合中创建一个表:
-- Oct 2017
select distinct a.device_id ,201710 as month_id,
case when group_descr in ('BASE') then 'Basic'
when group_descr in ('VALUES') then 'Valuable'
when group_descr in ('PREFERRENCE') then 'Preferr'
else 'Other'
end as Class
from dbo.DEVICE_HIST a
where a.expired >= '2017-10-01' and a.EFFTV <'2017-10-31'
union
-- Nov 2017
select distinct a.device_id ,201711 as month_id,
case when group_descr in ('BASE') then 'Basic'
when group_descr in ('VALUES') then 'Valuable'
when group_descr in ('PREFERRENCE') then 'Preferr'
else 'Other'
end as Class
from dbo.DEVICE_HIST a
where a.expired >= '2017-11-01' and a.EFFTV <'2017-11-30'
union
-- Dec 2017
select distinct a.device_id ,201712 as month_id,
case when group_descr in ('BASE') then 'Basic'
when group_descr in ('VALUES') then 'Valuable'
when group_descr in ('PREFERRENCE') then 'Preferr'
else 'Other'
end as Class
from dbo.DEVICE_HIST a
where a.expired >= '2017-12-01' and a.EFFTV <'2017-12-31'
union
-- Jan 2018
select distinct a.device_id ,201801 as month_id,
case when group_descr in ('BASE') then 'Basic'
when group_descr in ('VALUES') then 'Valuable'
when group_descr in ('PREFERRENCE') then 'Preferr'
else 'Other'
end as Class
from dbo.DEVICE_HIST a
where a.expired >= '2018-01-01' and a.EFFTV <'2018-01-31'
这是每月运行一次,基于当前月份,我们需要从上个月取 3 个月的数据 - 1,向后。 例如,如果在 2 月运行,则应从 10 月至 12 月运行,如果在 3 月运行,则应从 11 月至 1 月运行。 这将基于当前月份,但有人可以帮我自动化吗?
需要当前月份并返回 - 1 个月,然后再从那里返回 3 个月。 虽然日期计算没有那么复杂,但是如何让查询根据当前月份动态变化呢?
【问题讨论】:
哪个版本的 SQL? SQL Server 2016 有一个 EOMonth() 函数,而以前的版本没有 您使用的是哪个 RDMS?您基本上需要更改所有这些硬编码的日期以使用函数获取今天的日期,然后查找当前月份的第一天/最后一天,然后是上个月,等等。但是语法将取决于您使用的数据库。跨度> 无关,但为了性能,最好使用UNION ALL
。另外,你为什么只用一个值使用IN
? in ('BASE')
与 = 'BASE'
相同。
a.expired
和a.EFFTV
是什么关系?两者都需要吗?
数据库是 PostGreSql,是的,a.expired 和 a.EFFTV 都需要。
【参考方案1】:
假设这是 SQL SERVER 2005+:
-- Oct 2017
select distinct a.device_id
,CONCAT(CAST(YEAR(a.expired) AS varchar(4)),right('00'+CAST(MONTH(a.expired) AS nvarchar(2)), 2)) as month_id,
case when group_descr in ('BASE') then 'Basic'
when group_descr in ('VALUES') then 'Valuable'
when group_descr in ('PREFERRENCE') then 'Preferr'
else 'Other'
end as Class
from @test a
where CONVERT(date, a.expired) >= DATEADD(month, DATEDIFF(month, 0, convert(date, DATEADD(MONTH, -3, GETDATE()))), 0)
【讨论】:
这并没有回答问题,但是既然被接受了,也许问题是错误的? @PeterAbolins:是的,我错过了 where 子句,因为我没有对真实数据进行测试。试图创建一个测试表,我将编辑我的答案 嗯...问题指定范围应该是3个月,但从一个月前开始。因此,您需要将getdate() - 4 months
匹配到getdate() - 1 month
。另外...如果只有一个值,in
将毫无意义。
in
可能在那里,因为他希望代码为将来添加更多值做好准备,但是是的,使用 = 运算符通常是正确的。 getdate() - 4 months
可能不正确,因为他可能会错过考虑月份的部分时间(例如,如果今天是 3 月 30 日并且他想要整个 12 月,他将错过第 1-29 天)以上是关于基于当月的动态 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章
sqlserver查询,按分公司、汇总当月的订单数量怎么写sql查询