January 11, 2024 at 6:04 am
I want to wrtie query where get count from previous month if match with key.
This is data we have
Output
1 record has match is 2 because it has in 2 subsequent previous month data was there with mainhost
2 record has match is 1 because it has in 1 subsequent previous month data was there with mainhost
3 record has match is 0 because it has in 0 subsequent previous month data was there with mainhost
4 record has match is 1 because it has in 1 subsequent previous month data was there with mainhost
5 record has match is 0 because it has in 0 subsequent previous month data was there with mainhost
6 record has match is 0 because it has in 0 subsequent previous month data was there with mainhost
Here is table definition
create table test_data ( id int , mainhost int, enter_date date )
insert into test_data Values ( 1 , 500 , '20231231') , ( 2 , 501 , '20231230') ,
( 3 , 500 , '20231130') , ( 4 , 500 , '20231031') , ( 5 , 501 , '20231130') ,
( 6 , 501 , '20230928')
select * from test_data
order by mainhost, enter_date desc
January 11, 2024 at 8:07 am
Use LAG or LEAD analytical functions.
https://learn.microsoft.com/en-us/sql/t-sql/functions/lag-transact-sql?view=sql-server-ver16
=======================================================================
January 11, 2024 at 9:08 am
Can you please confirm this statement:
1 record has match is 2 because it has in 2 subsequent previous month data was there with mainhost
You are referring to the 2023-12-31 row, with mainhost 500.
But there is only one row in 2023-11, with mainhost = 500. So why is match 2 and not 1?
The absence of evidence is not evidence of absence.
Martin Rees
You can lead a horse to water, but a pencil must be lead.
Stan Laurel
January 11, 2024 at 10:11 am
WITH MonthCheck
AS
(
SELECT mainhost, enter_date
,IIF(MONTH(enter_date) - 1
= LEAD(MONTH(enter_date)) OVER (PARTITION BY mainhost ORDER BY enter_date DESC)
, 1, 0) AS IsPrevMonth
FROM test_data
)
,Grps
AS
(
SELECT mainhost, enter_date, IsPrevMonth
,SUM(IsPrevMonth ^ 1) OVER (PARTITION BY mainhost ORDER BY enter_date DESC) AS Grp
FROM MonthCheck
)
SELECT mainhost, enter_date
,IIF(IsPrevMonth = 0, 0
,SUM(IsPrevMonth) OVER (PARTITION BY mainhost, Grp ORDER BY enter_date)
) AS [Match]
FROM Grps
ORDER BY mainhost, enter_date DESC;
January 11, 2024 at 3:22 pm
Can you please confirm this statement:
1 record has match is 2 because it has in 2 subsequent previous month data was there with mainhost
You are referring to the 2023-12-31 row, with mainhost 500.
But there is only one row in 2023-11, with mainhost = 500. So why is match 2 and not 1?
I believe it's because, for Dec, previous rows exist for both Nov and Oct, i.e., two consecutive previous months.
SQL DBA,SQL Server MVP(07, 08, 09) "It's a dog-eat-dog world, and I'm wearing Milk-Bone underwear." "Norm", on "Cheers". Also from "Cheers", from "Carla": "You need to know 3 things about Tortelli men: Tortelli men draw women like flies; Tortelli men treat women like flies; Tortelli men's brains are in their flies".
January 11, 2024 at 3:33 pm
Ken's code is nice, but theoretically I believe it could yield a false positive if the previous month happened to be 13 months prior to the current month. For example, Feb 2023 followed by Jan 2022.
SQL DBA,SQL Server MVP(07, 08, 09) "It's a dog-eat-dog world, and I'm wearing Milk-Bone underwear." "Norm", on "Cheers". Also from "Cheers", from "Carla": "You need to know 3 things about Tortelli men: Tortelli men draw women like flies; Tortelli men treat women like flies; Tortelli men's brains are in their flies".
January 11, 2024 at 4:25 pm
This query looks for the minimum previous appropriate enter_date for each row and then calculates the DATEDIFF. The sample was expanded to include a greater than 12 month gap
drop table if exists #test_data;
go
create table #test_data ( id int , mainhost int, enter_date date );
insert into #test_data Values
( 1 , 500 , '20231231') , ( 2 , 501 , '20231230') ,
( 3 , 500 , '20231130') , ( 4 , 500 , '20231031') , ( 5 , 501 , '20231130') ,
( 6 , 501 , '20230928'),
( 7 , 500 , '20220928'),
( 11 , 500 , '20220828'),
( 8 , 501 , '20230628'),
( 9 , 501 , '20230528'),
( 10 , 501 , '20230428');
with data_cte as (
select *, row_number() over (partition by mainhost order by enter_date desc) rn
from #test_data)
select *, isnull(datediff(month, prev_dt.min_dt, d.enter_date), 0) dt_diff
from data_cte d
outer apply (select min(dc.enter_date)
from data_cte dc
where dc.mainhost=d.mainhost
and dc.enter_date<d.enter_date
and datediff(month, dc.enter_date, d.enter_date)=(dc.rn-d.rn)) prev_dt(min_dt);
Aus dem Paradies, das Cantor uns geschaffen, soll uns niemand vertreiben können
January 11, 2024 at 8:01 pm
Ken's code is nice, but theoretically I believe it could yield a false positive if the previous month happened to be 13 months prior to the current month. For example, Feb 2023 followed by Jan 2022.
You are, of course, correct. I was thinking that the test data did not include the group possibility and did not look at anything else.
MONTH(enter_date) should be replaced with:
(YEAR(enter_date) * 100 + MONTH(enter_date))
January 12, 2024 at 1:24 am
yes that is right two consecutive previous months.
January 12, 2024 at 1:46 am
Thank you everyone for your help. Looks good with both solution.
Viewing 10 posts - 1 through 9 (of 9 total)
You must be logged in to reply to this topic. Login to reply