简体   繁体   中英

Finding Quarter of year in SQL Server

I have a database that contains financial info of banks.

This is the table structure. For the sake of simplicity I have made Assets int.

create table dbo.BankInfo
(
     id int, 
     asofdate date, 
     Assets int
)

insert into dbo.BankInfo Values(1,'2018-01-31',100)
insert into dbo.BankInfo Values(1,'2017-10-31',200)
insert into dbo.BankInfo Values(1,'2017-07-31',300)
insert into dbo.BankInfo Values(1,'2017-04-30',400)
insert into dbo.BankInfo Values(1,'2017-01-31',40)
insert into dbo.BankInfo Values(1,'2016-10-31',20)

insert into dbo.BankInfo Values(2,'2016-12-31 00:00:00',100)
insert into dbo.BankInfo Values(2,'2017-03-31 00:00:00',200)
insert into dbo.BankInfo Values(2,'2017-06-30 00:00:00',300)
insert into dbo.BankInfo Values(2,'2017-09-30 00:00:00',400)
insert into dbo.BankInfo Values(2,'2017-12-31 00:00:00',300)
insert into dbo.BankInfo Values(2,'2016-03-31 00:00:00',400)

I have another table that contains info of each bank's Fiscal yearenddate

create table dbo.yearenddate
(
     id int, 
     enddate date
)

insert into dbo.yearenddate values(1,'2018-01-31  00:00:00')
insert into dbo.yearenddate values(2,'2017-06-30 00:00:00')

I want to look at dbo.BankInfo , get the Fiscalyearenddate for each bank and set the Quarter (Qtr=4) and others follow the same pattern

This is how the output looks like. I am unable to do this by rank.

create table dbo.outputqtr
(
     id int, 
     asofdate date, 
     Assets int, 
     qtr smallint
)

insert into dbo.outputqtr Values(1,'2018-01-31',100,4)
insert into dbo.outputqtr Values(1,'2017-10-31',200,3)
insert into dbo.outputqtr Values(1,'2017-07-31',300,2)
insert into dbo.outputqtr Values(1,'2017-04-30',400,1)
insert into dbo.outputqtr Values(1,'2017-01-31',40,4)
insert into dbo.outputqtr Values(1,'2016-10-31',20,3)

insert into dbo.outputqtr Values(2,'2016-12-31 00:00:00',100,2)
insert into dbo.outputqtr Values(2,'2017-03-31 00:00:00',200,3)
insert into dbo.outputqtr Values(2,'2017-06-30 00:00:00',300,4)
insert into dbo.outputqtr Values(2,'2017-09-30 00:00:00',400,1)
insert into dbo.outputqtr Values(2,'2017-12-31 00:00:00',300,2)
insert into dbo.outputqtr Values(2,'2016-03-31 00:00:00',400,3)

The query I have is

SELECT 
    *,
    CASE 
       WHEN qtrr = 4 THEN 4
       ELSE DENSE_RANK() OVER(PARTITION BY ID, MONTH(asofdate)
                              ORDER BY asofdate DESC) 
    END AS qtr
FROM
    (SELECT
         t.*, y.enddate,
         CASE 
            WHEN AsofDate = enddate THEN 4
            ELSE 1
         END AS qtrr
     FROM
         dbo.BankInfo t
     LEFT JOIN
         dbo.yearenddate y ON y.id = t.id AND t.asofdate = y.enddate) t

Any help is appreciated

It looks like all you need is to calculate the number of months from the anchor date from the yearenddate table and then convert that number into quarters.

Examine intermediate results of the formula below to understand how it works.

Sample data

DECLARE @BankInfo TABLE
(
    id int, 
    asofdate date, 
    Assets int
);

insert into @BankInfo Values(1,'2018-01-31',100)
insert into @BankInfo Values(1,'2017-10-31',200)
insert into @BankInfo Values(1,'2017-07-31',300)
insert into @BankInfo Values(1,'2017-04-30',400)
insert into @BankInfo Values(1,'2017-01-31',40)
insert into @BankInfo Values(1,'2016-10-31',20)

insert into @BankInfo Values(2,'2016-12-31',100)
insert into @BankInfo Values(2,'2017-03-31',200)
insert into @BankInfo Values(2,'2017-06-30',300)
insert into @BankInfo Values(2,'2017-09-30',400)
insert into @BankInfo Values(2,'2017-12-31',300)
insert into @BankInfo Values(2,'2016-03-31',400)

DECLARE @yearenddate TABLE
(
    id int, 
    enddate date
)

insert into @yearenddate values(1,'2018-01-31')
insert into @yearenddate values(2,'2017-06-30')

Query

SELECT
    B.id
    ,B.asofdate
    ,B.Assets
    ,(DATEDIFF(month, EOY.enddate, B.asofdate) / 3 + 399) % 4 + 1 AS qtr
FROM
    @BankInfo AS B
    INNER JOIN @yearenddate AS EOY ON B.id = EOY.id
;

Result

+----+------------+--------+-----+
| id |  asofdate  | Assets | qtr |
+----+------------+--------+-----+
|  1 | 2018-01-31 |    100 |   4 |
|  1 | 2017-10-31 |    200 |   3 |
|  1 | 2017-07-31 |    300 |   2 |
|  1 | 2017-04-30 |    400 |   1 |
|  1 | 2017-01-31 |     40 |   4 |
|  1 | 2016-10-31 |     20 |   3 |
|  2 | 2016-12-31 |    100 |   2 |
|  2 | 2017-03-31 |    200 |   3 |
|  2 | 2017-06-30 |    300 |   4 |
|  2 | 2017-09-30 |    400 |   1 |
|  2 | 2017-12-31 |    300 |   2 |
|  2 | 2016-03-31 |    400 |   3 |
+----+------------+--------+-----+

Below query should give you expected results.

;with CTE AS 
     (
         SELECT t.*, y.enddate,
        datediff(MONTH, AsofDate,   enddate)%12 QTRY                              
         FROM dbo.BankInfo t   CROSS APPLY  dbo.yearenddate y 
         where y.id = t.id
     )
     select ID,AsOfDate,Assets, CASE WHEN QTRY=0 THEN 4 WHEN QTRY<0 THEN ABS(QTRY)/3 ELSE 4-QTRY/3 END AS QTR
     FROM CTE

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM