获取每月的所有日期,然后将数据映射到特定日期

时间:2016-07-06 07:11:22

标签: sql-server sql-server-2008-r2

我创建了一个图表,用于绘制数据以显示特定日期的当前数据的值

使用此SQL

select substring(TRAN_DATE, 1, 4) MONTH, substring(TRAN_DATE, 5, 2) DATE, count(*) AMOUNT from  TA1606 group by TRAN_DATE

这是字段结构

 TRAN_DATE  char(6)

使用此create命令

CREATE TABLE [dbo].[TA16](
    [TRAN_DATE] [char](6) NULL,
    [TERM] [char](16) NULL,
)

我的结果是

MONTH   DATE    AMOUNT
1606    03        44  

但这只是一行一天 我需要获得示例中的所有日期06 June它将查询当月的所有日期,然后将数据映射到date,如上所示我的结果

这是我的预期结果

    MONTH   DATE    AMOUNT
1606          1     0
1606          2     0
1606          3     44
1606          4     0
1606          5     0
1606          6     0
1606          7     0
1606          8     0 
1606          9     0
1606          10    0
1606          11    0
1606          12    0
1606          13    0
1606          14    0
1606          15    0
1606          16    0
1606          17    0
1606          18    0
1606          19    0
1606          20    0
1606          21    0
1606          22    0
1606          23    0
1606          24    0
1606          25    0
1606          26    0
1606          27    0
1606          28    0
1606          29    0
1606          30    0

2 个答案:

答案 0 :(得分:1)

基本上,我们的想法是在日历表和数据表之间使用左连接。 有很多方法可以创建日历表,我喜欢使用计数表。 所以你应该做的第一件事,如果你还没有计数表,那就是create one 如果您问自己什么是计数表,为什么需要它,read this article by Jeff Moden

SELECT TOP 1001 IDENTITY(int,0,1) AS Number
    INTO Tally
    FROM sys.objects s1       
    CROSS JOIN sys.objects s2 
ALTER TABLE Tally ADD CONSTRAINT PK_Tally PRIMARY KEY CLUSTERED (Number)

现在,创建并填充示例数据(在下一个问题中将此步骤保存为我们)

DECLARE @TA16 TABLE (
    [TRAN_DATE] [char](6) NULL,
    [TERM] [char](16) NULL
)

INSERT INTO @TA16 VALUES ('160603', '44')

然后,使用CTE创建相关年份(或月份,适合您的最佳状态)的日历, 由于您使用char来保留日期,我们需要另一个cte convert将char值设置为正确的日期。

;With Calendar as
(
    SELECT DATEADD(DAY, Number, '2016-01-01') TheDate
    FROM Tally 
    WHERE Number < 367 -- Most years are 365 days, but leap years are 366, so it will cover leap years as well
), TA16WithActualDate AS
(
    SELECT  [TRAN_DATE], 
            [TERM],
            CONVERT(date, LEFT([TRAN_DATE], 2) +'.'+ SUBSTRING ([TRAN_DATE], 3, 2) +'.'+ RIGHT([TRAN_DATE], 2), 2) As ActualDate
    FROM @TA16
)

现在,从Calendar left joined选择TA16WithActualDate cte并根据需要格式化输出:

SELECT  REPLACE(CONVERT(char(5), TheDate, 2), '.', '') As [Month],  
        RIGHT(CONVERT(char(8), TheDate, 2), 2) As [Date],
        ISNULL([TERM], 0) As Amount
FROM Calendar
LEFT JOIN TA16WithActualDate ON TheDate = TRAN_DATE
WHERE MONTH(TheDate) = 6

结果:

Month Date Amount
--- ---- ------
1606  01   0               
1606  02   0               
1606  03   44              
1606  04   0               
1606  05   0               
1606  06   0               
1606  07   0               
1606  08   0               
1606  09   0               
1606  10   0               
1606  11   0               
1606  12   0               
1606  13   0               
1606  14   0               
1606  15   0               
1606  16   0               
1606  17   0               
1606  18   0               
1606  19   0               
1606  20   0               
1606  21   0               
1606  22   0               
1606  23   0               
1606  24   0               
1606  25   0               
1606  26   0               
1606  27   0               
1606  28   0               
1606  29   0               
1606  30   0    

答案 1 :(得分:0)

试试这个,

SELECT TOP 1 substring(TRAN_DATE, 1, 4) MONTH
    ,substring(TRAN_DATE, 5, 2) DATE
    ,count(*) AMOUNT
FROM TA1606
GROUP BY TRAN_DATE
ORDER BY 3 DESC

这个查询可能会给出这样的结果。

MONTH   DATE  AMOUNT
1606   3     44