Sql 如何为一年中的几周生成包含整数1-52的临时表?
我需要创建一个临时表,我认为它包含一个值为1到52的WeekID字段,表示日历年的每个星期。我希望能够在周数上与此表左键联接,基于一些数据,我必须指出一年中每周的总数 最好在单个查询中执行此操作 我在过去5周内使用的是有记录的输出,而实际的过去5周内,总计可能为0 下面是我的错误查询,它给出了最近5周实际打开门票的总数:Sql 如何为一年中的几周生成包含整数1-52的临时表?,sql,sql-server,Sql,Sql Server,我需要创建一个临时表,我认为它包含一个值为1到52的WeekID字段,表示日历年的每个星期。我希望能够在周数上与此表左键联接,基于一些数据,我必须指出一年中每周的总数 最好在单个查询中执行此操作 我在过去5周内使用的是有记录的输出,而实际的过去5周内,总计可能为0 下面是我的错误查询,它给出了最近5周实际打开门票的总数: SET DATEFIRST 1 SELECT TOP 5 * FROM (SELECT TOP 5 DATEPART(year, t.TicketQue
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
电流输出:
这很有效;但是,我想显示实际过去5周的实际总数,即使没有任何票证,也应该在有空白周且没有票证的情况下填写0输出
预期输出假设为了这篇文章,我们在第33周,本周没有门票:
TicketYear TicketWeek WeekTotal
2018 29 2
2018 30 0
2018 31 0
2018 32 1
2018 33 0
注:无票证缺口的周数用0值填充,并反映了包括当前周在内的实际最后5周数
MSSQL 2016企业版您可以通过多种方式生成这样的表。如果您的数据库中还没有一个计数表,即一个包含顺序整数的表,我建议您创建一个,因为它们的用处是无穷的。无论如何,您可以使用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
我重用了@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:我无法测试这一点,如果您正在寻找性能,那么这可能不是最好的查询。但是请尝试一下,如果它对您有效,我们可以致力于提高性能
干杯 无需创建临时表,您可以使用CTE简化此查询,如下所示。 -使用递归CTE生成周数 -从售票处获得不同的年份 -交叉连接不同的年份和周以获得所有组合 -然后左加入它的票务,以获得每年每周的计数
;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
这正是在一个查询中完成所有操作的方法。但我要重申其中一个答案所说的,并创建一个标准的计数表或数字表,填充从1到大的整数,因为这样一个表的用途是无限的。在我的数据库中,我总是有一个表n,其中有一个列n,它将直接插入上面的查询中,而不是CTE,其中的where n子句介于1和52之间
;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