如何将这个新的自定义列添加到查询的输出中?

时间:2019-03-25 06:14:34

标签: sql sql-server tsql

我正在使用SQL Server 2014,并且具有以下T-SQL查询:

SELECT 
    [Date],
    (CASE
        WHEN [Date] BETWEEN '2016-07-01' AND '2017-06-30' THEN 'FY 16-17'
        WHEN [Date] BETWEEN '2017-07-01' AND '2018-06-30' THEN 'FY 17-18'
        WHEN [Date] BETWEEN '2018-07-01' AND '2019-06-30' THEN 'FY 18-19'
        ELSE 'Not Stated'
     END) AS [Period]
FROM 
    DateDimension
WHERE  
    [Date] BETWEEN '2016-07-01' AND '2019-06-30'

输出如下(摘录):

Date          Period
-----------------------
2016-07-01    FY 16-17
2016-07-02    FY 16-17
2016-07-03    FY 16-17
...           ...
2017-07-01    FY 17-18
2017-07-02    FY 17-18
2017-07-03    FY 17-18
...           ...
2018-07-01    FY 18-19
2018-07-02    FY 18-19
2018-07-03    FY 18-19
...           ...

我想在输出中添加一个新列,如下所示:

    Date          Period       Day
    -------------------------------
    2016-07-01    FY 16-17     D1
    2016-07-02    FY 16-17     D2
    2016-07-03    FY 16-17     D3
    ...           ...          ...
    2017-07-01    FY 17-18     D1
    2017-07-02    FY 17-18     D2
    2017-07-03    FY 17-18     D3
    ...           ...          ...
    2018-07-01    FY 18-19     D1
    2018-07-02    FY 18-19     D2
    2018-07-03    FY 18-19     D3
    ...           ...          ...

请注意,D1在每个新的财政年度开始(即2016-07-012017-07-012018-07-01)重新开始。

如何为新列编写SQL代码?

附加说明:D1应该持续到每个财政年度结束。例如,从2016-07-012017-06-30,列Period将显示D1,D2,...,D365)

5 个答案:

答案 0 :(得分:0)

您可以使用DATEDIFF来获取会计年度开始与[Date]之间的天数差异。

SELECT 

[Date]
,(CASE WHEN [Date] between '2016-07-01' and '2017-06-30' THEN 'FY 16-17'
  WHEN [Date] between '2017-07-01' and '2018-06-30' THEN 'FY 17-18'
  WHEN [Date] between '2018-07-01' and '2019-06-30' THEN 'FY 18-19'
  ELSE 'Not Stated'
  END) as [Period]
, CASE WHEN [Date] < DATEFROMPARTS(DATEPART(Year, GETDATE()), 7, 1)
       THEN CONCAT('D', (DATEDIFF(DAY, DATEFROMPARTS(DATEPART(Year, [Date]) - 1, 7, 1), [Date] + 1)))
       ELSE CONCAT('D', (DATEDIFF(DAY, DATEFROMPARTS(DATEPART(Year, [Date]), 7, 1), [Date] + 1)))
  END AS [Day]

FROM DateDimension

WHERE [Date] between '2016-07-01' and '2019-06-30'

此方法还意味着日期可以按任何顺序排列,甚至可能缺少几天,并且Day列仍应正确。

答案 1 :(得分:0)

这里是一个示例,您可以通过它简化现有的FY计算并获得财务年度的日期:

declare @date date = '20190702';

select year(dateadd(month, -6, @date)) as [FY],
  datediff(day, datefromparts(year(dateadd(month, -6, @date)), 6, 30), @date) as [DOFY];

如果需要,还可以参数化指定日历和财务年度之间的偏移量的硬编码常量。

答案 2 :(得分:0)

您可以使用DATEDIFF计算该财政年度的天数。您只需付出额外的努力即可获取DATE列的“财政年度”的第一天。

DECLARE @DateDimension TABLE ([DATE] DATETIME)
INSERT INTO @DateDimension
SELECT '2019-03-25' 
UNION ALL 
SELECT '2018-12-06'
UNION ALL 
SELECT '2018-05-15'
UNION ALL 
SELECT '2017-11-22'
UNION ALL 
SELECT '2019-07-06'

SELECT  [DATE]
,'D'+CAST( DATEDIFF(DD, CASE WHEN MONTH([DATE]) BETWEEN 7 AND 12 
        THEN DATEFROMPARTS(YEAR([DATE]),07,01) 
        ELSE DATEFROMPARTS(YEAR([DATE])-1,07,01) END,[DATE])+1 
    AS VARCHAR(3)) AS DAY_IN_FY
FROM @DateDimension

结果:

+-------------------------+-----------+
|          DATE           | DAY_IN_FY |
+-------------------------+-----------+
| 2019-03-25 00:00:00.000 | D268      |
| 2018-12-06 00:00:00.000 | D159      |
| 2018-05-15 00:00:00.000 | D319      |
| 2017-11-22 00:00:00.000 | D145      |
| 2019-07-06 00:00:00.000 | D6        |
+-------------------------+-----------+

答案 3 :(得分:0)

我想指出您可以将查询表示为:

SELECT d.[Date], v.period,
       CONCAT('D', ROW_NUMBER() OVER (PARTITION BY period ORDER BY date)) as [Day]
FROM DateDimension dd CROSS APPLY
     (VALUES (RIGHT(DATENAME(year, d.[Date]), 2) + '-' +
              RIGHT(DATENAME(year, DATEADD(year, 1, d.[Date])), 2) 
             )
     ) as v(period)
WHERE [Date] BETWEEN '2016-07-01' AND '2019-06-30';

period也可以定义为:

     (VALUES (CONCAT(YEAR([Date] % 100, '-',
                     1 + YEAR([Date] % 100
                    )
             )
     ) as v(period)

答案 4 :(得分:-1)

使用row_number()

with cte as
(
 SELECT [Date]
,(CASE WHEN [Date] between '2016-07-01' and '2017-06-30' THEN 'FY 16-17'
      WHEN [Date] between '2017-07-01' and '2018-06-30' THEN 'FY 17-18'
      WHEN [Date] between '2018-07-01' and '2019-06-30' THEN 'FY 18-19'
      ELSE 'Not Stated'
      END) as [Period]
FROM DateDimension
)

select *,concat('D',row_number() over(partition by period order by date)) as DayNo
    from cte