简体   繁体   中英

How to compare the current month value with last 12 months

I'm trying to compare the current month value with the last 12 months values.

E.g:
6/30/2019 100
5/31/2019 90
4/30/2019 80
3/31/2019 70
2/8/2019 60
1/31/2019 50
12/31/2018 40
11/30/2018 30
10/31/2018 20
9/30/2018 10
8/31/2018 90
7/30/2018 110

Now the current month value(6/30/2019) in 100 then I want to compare these value with the last 12 months values. If the current month value is the maximum when compared with the 12 months then I want to set the flag as "max". In the above example, 110 is the maximum but current month 100 ie, it is minimum when compared with the last 12 months values then I want to set the flag as "min".

Also, I want to get the date also ie, if it is minimum then what is the maximum value with the date (expected output "MIN(110 as on 7/30/2018)").

Please provide me any solution to achieve this scenario

expected output "MIN(110 as on 7/30/2018)"

If I understand correctly, here's one way to do it:

-- Create a table variable to hold the sample data
DECLARE @data TABLE (
    [Date] DATE,
    [Value] INT
)

-- Load the sample data table
DECLARE @i INT = 0;
WHILE @i < 12
BEGIN
    INSERT INTO @data ([Date], [Value]) values (EOMONTH(DATEADD(M,-@i, GETDATE())), FLOOR(RAND()*(100-1+1))+10);
    SET @i = @i + 1;
END;

-- Select the resulting data set with flags
WITH t as
(
SELECT [Date], [Value], 
    CASE 
        WHEN [Value] = (SELECT MAX([Value]) FROM @data) THEN 'MAX' 
        WHEN [Value] = (SELECT MIN([Value]) FROM @data) THEN 'MIN' 
        ELSE '' 
    END AS Flag 
FROM @data
)
SELECT 'MAX(' + CAST([Value] as VARCHAR(MAX)) + ' as on ' + CAST([Date] as VARCHAR(MAX)) + ')' FROM t WHERE [Flag] = 'MAX'

This will output:

MAX(109 as on 2018-09-30)

Swap "MIN" for "MAX" and you'll have the minimum value.

If you want to compare the current value to a rolling 12-month min/max, you can use window functions:

select top (1) t.*,
       (case when value = max12_value then 'MAX'
             when value = min12_value then 'MIN'
        end) as flag
from (select t.*,
             max(value) over (order by date rows between 11 preceding and current row) as max12_value,
             min(value) over (order by date rows between 11 preceding and current row) as min12_value,
      from t
     ) t
order by date desc

This following script will give you output considering the current month value always calculated from GETDATE()

WITH CTE (d, value)
AS
(
    SELECT id,value FROM your_table
),
CTE2
AS
(
    SELECT DISTINCT
    (SELECT Value FROM CTE WHERE d>= CAST(DATEADD(DD,-DATEPART(DD,GETDATE()) + 1,GETDATE())  AS DATE)) current_month_value,
    MIN(value) min_value,
    MAX(value) max_value
    FROM CTE
    WHERE d <  CAST(DATEADD(DD,-DATEPART(DD,GETDATE()) + 1,GETDATE())  AS DATE)
    AND d >= CAST(DATEADD(MM,-13,DATEADD(DD,-DATEPART(DD,GETDATE()) + 1,GETDATE()) ) AS DATE)
)

SELECT 
CASE 
    WHEN  current_month_value > max_value THEN 'MAX'
    ELSE 'MIN(' + CAST(max_value AS VARCHAR)+ ' AS ON '+ (SELECT TOP 1 CAST(d AS VARCHAR) FROM CTE WHERE Value = max_value)+ ')'
END
FROM CTE2

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