Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何为一年中的几周生成包含整数1-52的临时表?_Sql_Sql Server - Fatal编程技术网

Sql 如何为一年中的几周生成包含整数1-52的临时表?

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

我需要创建一个临时表,我认为它包含一个值为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
电流输出:

这很有效;但是,我想显示实际过去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