我需要创建一个临时表(我认为),该表包含一个值为1到52的WeekID字段,以指示日历年的每个星期。我希望能够根据一些我必须指出一年中每个星期的总数的数据,在星期几的表格上保留该联接。
最好是在单个查询中执行此操作。
我一直在使用的是最近5周记录存在的记录,而不是实际最近5周记录的总计为0。
以下是我的错误查询,该查询提供了过去5周的实际开票总数:
SET DATEFIRST 1
SELECT TOP 5 * FROM
(SELECT TOP 5
DATEPART(year, t.TicketQueuedDateTime) AS 'TicketYear',
DATEPART(week, t.TicketQueuedDateTime) AS 'TicketWeek',
COUNT(t.TicketStatus) AS 'WeekTotal'
FROM TicketTable t
GROUP BY DATEPART(year, t.TicketQueuedDateTime), DATEPART(week, t.TicketQueuedDateTime)
ORDER BY TicketYear DESC, TicketWeek DESC) val
ORDER BY val.TicketYear, val.TicketWeek
当前输出:
TicketYear TicketWeek WeekTotal
2018 25 13
2018 26 10
2018 27 4
2018 29 2
2018 32 1
这很好用;但是,即使没有票证,我也想显示最近5周的实际总数(在有“票证”周的情况下也没有票证的情况下,应填写“ 0”输出)。 / p>
预期的产量(由于这篇文章,我们在第33周,而本周没有门票:
TicketYear TicketWeek WeekTotal
2018 29 2
2018 30 0
2018 31 0
2018 32 1
2018 33 0
(注意:没有票务差额的周用“ 0”值填充,并反映了包括当前周在内的实际最近5周)
MSSQL 2016企业版
答案 0 :(得分:1)
您可以通过多种方式生成此类表。如果您的数据库中没有统计表(即其中包含顺序整数的表),则建议创建一个统计表,因为它们的用途无穷。无论如何,您都可以使用row_number()
即时创建一个。然后只需从当前日期(以周为单位)中减去您生成的整数值,然后选择em的前52位即可。除去年份和星期,您我的朋友,就得到了用于填充联接表的查询。
-- Creating a numbers table
if object_id('tempdb.dbo.#Numbers') is not null drop table #Numbers
create table #Numbers
(
num int primary key clustered
)
-- Populating it with some numbers
insert into #Numbers (num)
select row_number() over (order by (select null)) - 1
from sys.all_objects
select top 52
WeeksAgo = num,
TicketYear = year(dateadd(week, -num, getdate())),
TicketWeek = datepart(week, dateadd(week, -num, getdate()))
from #Numbers
答案 1 :(得分:1)
无需创建临时表,可以使用CTE
简化此查询,如下所示。
-使用递归CTE
生成星期数
-从TicketTable
获得不同的年份
-Cross join
不同的年和周来获得所有组合
-然后,将left join
与TicketTable
一起count
;With WEEK_CTE as (
Select 1 as WeekNo
UNION ALL
SELECT 1 + WeekNo from WEEK_CTE
WHERE WeekNo < 52
)
Select yr.Year AS 'TicketYear'
, wk.WeekNo AS 'TicketWeek'
, COUNT(t.TicketStatus) AS 'WeekTotal'
from Week_CTE wk
cross join (select distinct year(TicketQueuedDateTime) as [Year] from TicketTable) yr
left join TicketTable t on wk.WeekNo = DATEPART(WEEK, t.TicketQueuedDateTime) and yr.Year = YEAR(t.TicketQueuedDateTime)
group by yr.Year, wk.WeekNo
答案 2 :(得分:0)
我重用了@Xedni的查询,并提出了以下查询:
if object_id('tempdb.dbo.#Numbers') is not null drop table #Numbers
create table #Numbers
(
num int primary key clustered
)
-- Populating it with some numbers
insert into #Numbers (num)
select row_number() over (order by (select null)) - 1
from sys.all_objects
select TicketYear = year(dateadd(week, -num, getdate())),
TicketWeek = datepart(week, dateadd(week, -num, getdate()))
from #Numbers
SELECT TOP 5 * FROM
(SELECT TOP 5
DATEPART(year, t.TicketQueuedDateTime) AS 'TicketYear',
DATEPART(week, t.TicketQueuedDateTime) AS 'TicketWeek',
COUNT(t.TicketStatus) AS 'WeekTotal'
FROM #Numbers as n
LEFT OUTER JOIN TicketTable as t ON year(dateadd(week, -n.num, getdate())) = t.DATEPART(year, t.TicketQueuedDateTime) AND datepart(week, dateadd(week, -n.num, getdate())) = DATEPART(week, t.TicketQueuedDateTime)
GROUP BY DATEPART(year, t.TicketQueuedDateTime), DATEPART(week, t.TicketQueuedDateTime)
ORDER BY TicketYear DESC, TicketWeek DESC) val
ORDER BY val.TicketYear, val.TicketWeek
PS:我无法对此进行测试,如果您正在寻找性能,那么这可能不是最好的查询。但是请尝试一下,如果它对您有用,我们可以努力提高性能。
干杯!