SQL-запрос для возврата финансового года и кварталов - PullRequest
0 голосов
/ 28 июня 2018

Существует таблица, в которой перечислены каждый из четырех годовых кварталов, а также их начальные / конечные дни и месяцы.

Учитывая эту таблицу и начальный год, скажем, 2017 года, как я могу получить список кварталов в (конце) формате даты и имени, например, в 3 квартале 2017 года, '06 / 30/2017 '?

Я пробовал это, но получаю только текущий квартал:

select q.QID, q.QuarterName, q.StartMonth, q.StartDay, q.EndMonth, q.EndDay,
datefromparts(datepart (yy, '1/1/2017'), q.StartMonth, q.StartDay) StartQuarter, 
datefromparts(datepart (yy, '6/28/2018'), q.EndMonth, q.EndDay) EndQuarter 
from Quarters q 
where datefromparts(datepart (yy, '6/28/2018'), q.EndMonth, q.EndDay) < '06/30/2018';

Таблица "Четверти" выглядит так:

QID QuarterName     StartMonth  StartDay    EndMonth    EndDay
1   First Quarter   10          1           12          31
2   Second Quarter  1           1           3           31
3   Third Quarter   4           1           6           30
4   Fourth Quarter  7           1           9           30

Не уверен, является ли это актуальным или нет, но он используется в среде .Net / C #.

Ответы [ 3 ]

0 голосов
/ 28 июня 2018

Возможно, другой вариант использует CHOOSE, поскольку ваш финансовый год сдвинут на один QTR

* ** 1003 тысяча два * Пример
Declare @Date1 date = '2017-10-01'

Select DateR1 = D
      ,DateR2 = EOMONTH(D)
      ,AsString = concat(choose(DatePart(QQ,D),'Q2','Q3','Q4','Q1'),' ',year(D)-IIF(DatePart(QQ,D)<4,1,0) )
      ,AsDate   = format(EOMonth(D),'MM/dd/yyyy')
From (
        Select Top (12) D=DateAdd(MONTH,-1+Row_Number() Over (Order By (Select Null)),@Date1) From  master..spt_values n1,master..spt_values n2
     ) A

Возвращает

DateR1      DateR2      AsString    AsDate
2017-10-01  2017-10-31  Q1 2017     10/31/2017
2017-11-01  2017-11-30  Q1 2017     11/30/2017
2017-12-01  2017-12-31  Q1 2017     12/31/2017
2018-01-01  2018-01-31  Q2 2017     01/31/2018
2018-02-01  2018-02-28  Q2 2017     02/28/2018
2018-03-01  2018-03-31  Q2 2017     03/31/2018
2018-04-01  2018-04-30  Q3 2017     04/30/2018
2018-05-01  2018-05-31  Q3 2017     05/31/2018
2018-06-01  2018-06-30  Q3 2017     06/30/2018
2018-07-01  2018-07-31  Q4 2017     07/31/2018
2018-08-01  2018-08-31  Q4 2017     08/31/2018
2018-09-01  2018-09-30  Q4 2017     09/30/2018
0 голосов
/ 28 июня 2018

Попробуйте это:

DECLARE @year INT = 2017;

WITH numbers(n) AS (
  SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1
  FROM       (VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9)) AS v1(x)
  CROSS JOIN (VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9)) AS v2(x)
)
SELECT CONCAT('Q', QID, ' ', @year + n) AS QuarterName, EndDate
FROM numbers
CROSS JOIN Quarters
CROSS APPLY (SELECT
  DATEFROMPARTS(@year + n - CASE WHEN QID = 1 THEN 1 ELSE 0 END, StartMonth, StartDay) AS StartDate,
  DATEFROMPARTS(@year + n - CASE WHEN QID = 1 THEN 1 ELSE 0 END, EndMonth, EndDay) AS EndDate
) AS CA
WHERE StartDate <= CURRENT_TIMESTAMP ORDER BY EndDate

Общее табличное выражение numbers генерирует числа от 0 до 99 ( см. Этот вопрос ). Они кросс-умножены на Quarters таблицу. Даты генерируются путем добавления @year к каждому числу и корректируются с первого квартала года. n принадлежит n - 1 th год. Перекрестное применение облегчает обращение к вычисленным значениям внутри предложений WHERE, SELECT и ORDER BY.

Результат:

| QuarterName | EndDate    |
|-------------|------------|
| Q1 2017     | 2016-12-31 |
| Q2 2017     | 2017-03-31 |
| Q3 2017     | 2017-06-30 |
| Q4 2017     | 2017-09-30 |
| Q1 2018     | 2017-12-31 |
| Q2 2018     | 2018-03-31 |
| Q3 2018     | 2018-06-30 |

SQL Fiddle с небольшими изменениями

0 голосов
/ 28 июня 2018

Кажется, это то, что вы хотите. Вы можете использовать рекурсивный CTE и игнорировать эту таблицу, чтобы сделать это в течение нескольких лет ...

declare @quarters table (QID int, QuarterName varchar(64), StartMonth int,  StartDay int,  EndMonth int,    EndDay int)
insert into @quarters
values

(1,'First Quarter',10,1,12,31),
(2,'Second Quarter',1,1,3,31),
(3,'Third Quarter',4,1,6,30),
(4,'Fourth Quarter',7,1,9,30)


declare @year int = '2018'

select
    *
    ,convert(varchar,convert(date,cast(@year as varchar) + right('0' + cast(EndMonth as varchar),2)  + cast(EndDay as varchar)),101) 
from @quarters

Или рекурсивный CTE ...

;with cte as(
    select 
        *
        ,EndDate = convert(date,convert(date,cast(datepart(year,@startDate) as varchar) + right('0' + cast(EndMonth as varchar),2)  + cast(EndDay as varchar)))
    from @quarters
    union all
    select
        Qid
        ,QuarterName
        ,StartMonth
        ,StartDay
        ,EndMonth
        ,EndDay
        ,dateadd(year,1,EndDate)
    from cte
    where datepart(year,EndDate) <= datepart(year,@endDate)
    )

select
        Qid
        ,QuarterName
        ,StartMonth
        ,StartDay
        ,EndMonth
        ,EndDay
        ,EndDate = convert(varchar,EndDate,101)
from cte
...