Sql 在日期查询中填写缺少的月份
我在微软SQL Server 2017上工作。 我正试图在数据查询中填充缺少的月份 查询是:Sql 在日期查询中填写缺少的月份,sql,sql-server,Sql,Sql Server,我在微软SQL Server 2017上工作。 我正试图在数据查询中填充缺少的月份 查询是: SELECT Concat(Datename(mm, temp1.InvoiceDate), '-', Datepart(yy, Getdate())) AS 'Date' , temp1.[Partner], Count(temp1.issues) AS 'Total' FROM temp1 GROUP BY temp1.InvoiceDate, temp1.[partner] ORDER
SELECT Concat(Datename(mm, temp1.InvoiceDate), '-', Datepart(yy, Getdate())) AS 'Date' , temp1.[Partner], Count(temp1.issues) AS 'Total'
FROM temp1
GROUP BY temp1.InvoiceDate, temp1.[partner]
ORDER BY Datepart(mm, temp1.InvoiceDate), temp1.[partner];
不要介意getdate,因为我将始终处理实际的年份数据
它向我展示了这个结果:
Date Partner Total
April-2020 Enterprise1, S.A. 1
May-2020 Enterprise2, S.A. 1
July-2020 Enterprise2, S.A. 2
这是正确的,但我也需要有丢失的月份,直到实际月份,即getdate实际月份,其中没有数据
比如:
Date Partner Total
January-2020 N/A 0
February-2020 N/A 0
March-2020 N/A 0
April-2020 Enterprise1, S.A. 1
May-2020 Enterprise2, S.A. 1
June-2020 N/A 0
July-2020 Enterprise2, S.A. 2
August-2020 N/A 0
September-2020 N/A 0
另外,我不想看到实际的几个月
PS:我不能在我的开发环境中使用t-SQL代码声明等
提前感谢。我将使用递归CTE生成一年的日期:
with dates as (
select datefromparts(year(getdate()), 1, 1) as yyyymm
union all
select dateadd(month, 1, yyyymm)
from dates
where yyyymm < getdate()
)
select d.yyyymm, t1.partner, count(t1.issues)
from dates d left join
temp1 t1
ON t1.InvoiceDate >= d.yyyymm AND
t1.InvoiceDate < dateadd(month, 1, d.yyyymm)
group by d.yyyymm, t1.partner
order by d.yyyymm, t1.partner;
我将使用递归CTE生成该年的日期:
with dates as (
select datefromparts(year(getdate()), 1, 1) as yyyymm
union all
select dateadd(month, 1, yyyymm)
from dates
where yyyymm < getdate()
)
select d.yyyymm, t1.partner, count(t1.issues)
from dates d left join
temp1 t1
ON t1.InvoiceDate >= d.yyyymm AND
t1.InvoiceDate < dateadd(month, 1, d.yyyymm)
group by d.yyyymm, t1.partner
order by d.yyyymm, t1.partner;
递归CTE的一种替代方法是使用数字表(有时也称为“tally”表)进行查询。只有12个月,因此可以在代码中枚举它,然后不需要递归。此外,为了输入年份,我添加了一个变量,该变量采用逗号分隔的列表。本例中的示例为2年,即2020年和2021年 像这样的
declare
@report_yrs varchar(100)='2020,2021';
with ent_cte(InvoiceDate, [Partner], [issues]) as
(select '2020-03-01', 'Enterprise1, S.A.', 'x'
union all
select '2020-04-01', 'Enterprise1, S.A.', 'x'
union all
select '2020-05-01', 'Enterprise1, S.A.', 'x'
union all
select '2020-12-01', 'Enterprise1, S.A.', 'x')
SELECT Concat(Datename(mm, dfp.dfp), '-', Datepart(yy, dfp.dfp)) AS [Date],
isnull(t.[Partner], 'N/A') [Partner], Count(t.issues) AS [Total]
FROM string_split(@report_yrs, ',') sp
cross join
(values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)) v(mo)
cross apply
(select datefromparts(cast(sp.[value] as int), v.mo, 1) dfp) dfp
left join
ent_cte t on dfp.dfp=t.InvoiceDate
GROUP BY dfp.dfp, t.[partner]
ORDER BY dfp.dfp, t.[partner];
输出
Date Partner Total
January-2020 N/A 0
February-2020 N/A 0
March-2020 Enterprise1, S.A. 1
April-2020 Enterprise1, S.A. 1
May-2020 Enterprise1, S.A. 1
June-2020 N/A 0
July-2020 N/A 0
August-2020 N/A 0
September-2020 N/A 0
October-2020 N/A 0
November-2020 N/A 0
December-2020 Enterprise1, S.A. 1
January-2021 N/A 0
February-2021 N/A 0
March-2021 N/A 0
April-2021 N/A 0
May-2021 N/A 0
June-2021 N/A 0
July-2021 N/A 0
August-2021 N/A 0
September-2021 N/A 0
October-2021 N/A 0
November-2021 N/A 0
December-2021 N/A 0
递归CTE的一种替代方法是使用数字表(有时也称为“tally”表)进行查询。只有12个月,因此可以在代码中枚举它,然后不需要递归。此外,为了输入年份,我添加了一个变量,该变量采用逗号分隔的列表。本例中的示例为2年,即2020年和2021年 像这样的
declare
@report_yrs varchar(100)='2020,2021';
with ent_cte(InvoiceDate, [Partner], [issues]) as
(select '2020-03-01', 'Enterprise1, S.A.', 'x'
union all
select '2020-04-01', 'Enterprise1, S.A.', 'x'
union all
select '2020-05-01', 'Enterprise1, S.A.', 'x'
union all
select '2020-12-01', 'Enterprise1, S.A.', 'x')
SELECT Concat(Datename(mm, dfp.dfp), '-', Datepart(yy, dfp.dfp)) AS [Date],
isnull(t.[Partner], 'N/A') [Partner], Count(t.issues) AS [Total]
FROM string_split(@report_yrs, ',') sp
cross join
(values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)) v(mo)
cross apply
(select datefromparts(cast(sp.[value] as int), v.mo, 1) dfp) dfp
left join
ent_cte t on dfp.dfp=t.InvoiceDate
GROUP BY dfp.dfp, t.[partner]
ORDER BY dfp.dfp, t.[partner];
输出
Date Partner Total
January-2020 N/A 0
February-2020 N/A 0
March-2020 Enterprise1, S.A. 1
April-2020 Enterprise1, S.A. 1
May-2020 Enterprise1, S.A. 1
June-2020 N/A 0
July-2020 N/A 0
August-2020 N/A 0
September-2020 N/A 0
October-2020 N/A 0
November-2020 N/A 0
December-2020 Enterprise1, S.A. 1
January-2021 N/A 0
February-2021 N/A 0
March-2021 N/A 0
April-2021 N/A 0
May-2021 N/A 0
June-2021 N/A 0
July-2021 N/A 0
August-2021 N/A 0
September-2021 N/A 0
October-2021 N/A 0
November-2021 N/A 0
December-2021 N/A 0
您将在数据库中只找到您放入其中的数据。 在这种情况下,建议添加一些datetime表,例如每天一行的日历表和一些其他表,如月、日、周 当在数据库中创建时,查询将变得简单而高效,而不是使用表值函数的递归查询,所有这些都将耗费大量的时间和过程 对于您的情况,这可以是:
CREATE TABLE T_MONTH
(
MONTH_NUM TINYINT PRIMARY KEY,
MONTH_NAME VARCHAR(16) NOT NULL UNIQUE
);
DECLARE @I INT = 1, @D DATE = '2000-01-01'
WHILE @I <= 12
BEGIN
INSERT INTO T_MONTH
SELECT @I, DATENAME(month, DATEADD(month, @I - 1, @D));
SET @I = @I + 1;
END
您将在数据库中只找到您放入其中的数据。 在这种情况下,建议添加一些datetime表,例如每天一行的日历表和一些其他表,如月、日、周 当在数据库中创建时,查询将变得简单而高效,而不是使用表值函数的递归查询,所有这些都将耗费大量的时间和过程 对于您的情况,这可以是:
CREATE TABLE T_MONTH
(
MONTH_NUM TINYINT PRIMARY KEY,
MONTH_NAME VARCHAR(16) NOT NULL UNIQUE
);
DECLARE @I INT = 1, @D DATE = '2000-01-01'
WHILE @I <= 12
BEGIN
INSERT INTO T_MONTH
SELECT @I, DATENAME(month, DATEADD(month, @I - 1, @D));
SET @I = @I + 1;
END
我尝试了您的代码,但SQL抛出了一个错误:DATEFROMPARTS不是可识别的内置函数名。我怎样才能让它工作?我在14.0.2027.2版本,所以它应该是兼容的。。。谢谢。@operamaxi。它在所有受支持的SQL Server版本中都可用:。我发现了错误,第一个括号从未闭合。你能编辑一下你的答案吗?我打赌这一改变会使它起作用。谢谢。找到了,它必须添加在getdate之后:选择datefrompartsyeargetdate,1,1作为yyyymm。谢谢我试过了,但它只显示了10月份之前的所有月份。它能显示到12月或9月的实际月份吗?谢谢。我尝试了你的代码,但是SQL抛出了一个错误:DATEFROMPARTS不是可识别的内置函数名。我怎样才能让它工作?我在14.0.2027.2版本,所以它应该是兼容的。。。谢谢。@operamaxi。它在所有受支持的SQL Server版本中都可用:。我发现了错误,第一个括号从未闭合。你能编辑一下你的答案吗?我打赌这一改变会使它起作用。谢谢。找到了,它必须添加在getdate之后:选择datefrompartsyeargetdate,1,1作为yyyymm。谢谢我试过了,但它只显示了10月份之前的所有月份。它能显示到12月或9月的实际月份吗?谢谢