如何生成一年中要加入的整数为1-52的临时表?

时间:2018-10-11 22:51:18

标签: sql sql-server

我需要创建一个临时表(我认为),该表包含一个值为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企业版

3 个答案:

答案 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 joinTicketTable一起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:我无法对此进行测试,如果您正在寻找性能,那么这可能不是最好的查询。但是请尝试一下,如果它对您有用,我们可以努力提高性能。

干杯!