Fetch the minimum start_Date and Maximum of End_Date - sql-server

I am using following query:
select * from (Select
[CLIENT_ID],
[CLIENT_NAME],
[SUPER_GROUP_ID],
[SUPER_GROUP],
[MASTER_GROUP_ID],
[MASTER_GROUP],
[SALES_GROUP_ID],
[SALES_GROUP],
[VOTING_ENTITY_ID],
[VOTING_ENTITY],
[COVERAGE_SPECIALITY],
[COVERAGE_FUND],
[MCM_CLASSIFICATION],
[START_DATE],
IsNull([END_DATE], GetDate()) as END_DATE,
ROW_NUMBER()OVER (partition by CLIENT_ID order by START_DATE desc, END_DATE ) as RNUM
FROM [mi_s_data].[dbo].[BI_CLIENT_CONTACT_MAPPING]
) CCMAP2
where CCMAP2.RNUM =1 and ccmap2.CLIENT_ID= '1-12W68I'
I want to assign RNUM for that record for which START_DATE is minimum and END_DATE is maximum

just change the order for START_DATE and END_DATE, hope this helps
ROW_NUMBER()OVER (partition by CLIENT_ID order by START_DATE, END_DATE desc ) as RNUM

SELECT
[CLIENT_ID],
MIN([START_DATE]) as START_DATE,
Max(IsNull([END_DATE], GetDate())) as END_DATE
FROM [mi_s_data].[dbo].[BI_CLIENT_CONTACT_MAPPING]
GROUP BY
[CLIENT_ID]

Related

Average day gap in between a repeat order for each product

Can someone please help me to find the average time between first and second purchase on a product level.
This is what I have written -
Select A.CustomerId,A.ProductId , A.OrderSequence, (Case WHEN OrderSequence = 1 THEN OrderDate END) AS First_Order_Date,
MAX(Case WHEN OrderSequence = 2 THEN OrderDate END) AS Second_Order_Date
From
(
Select t.CustomerId, t.ProductId, t.OrderDate,
Dense_RANK() OVER (PARTITION BY t.CustomerId, t.ProductId ORDER BY OrderDate Asc) as OrderSequence
From Transactions t (NOLOCK)
Where t.SiteKey = 01
Group by t.CustomerId, t.ProductId, t.OrderDate)
A
Where A.OrderSequence IN (1,2)
Group By A.Customer_Id, A.ProductId, A.OrderSequence, A.OrderDate
Sample Data:
It looks like row-numbering and LEAD should do the trick for you here.
Don't use NOLOCK unless you really know what you're doing
It's unclear if you want the results to be partitioned by CustomerId also. If not, you can remove it everywhere in the query
SELECT
A.CustomerId,
A.ProductId,
AVG(DATEDIFF(day, OrderDate, NextOrderDate))
FROM
(
SELECT
t.CustomerId,
t.ProductId,
t.OrderDate,
ROW_NUMBER() OVER (PARTITION BY t.CustomerId, t.ProductId ORDER BY OrderDate) AS rn,
LEAD(OrderDate) OVER (PARTITION BY t.CustomerId, t.ProductId ORDER BY OrderDate) AS NextOrderDate
FROM Transactions t
WHERE t.SiteKey = '01'
) t
WHERE t.rn = 1
GROUP BY
t.Customer_Id,
t.ProductId;

Multi - Columns OVERLAPPING DATES

;with cte as (
select Domain_Id, Starting_Date, End_Date
from Que_Date
union all
select t.Domain_Id, cte.Starting_Date, t.End_Date
from cte
join Que_Date t on cte.Domain_Id = t.Domain_Id and cte.End_Date = t.Starting_Date),
cte2 as (
select *, rn = row_number() over (partition by Domain_Id, End_Date order by Domain_Id)
from cte
)
select DISTINCT Domain_Id, Starting_Date, max(End_Date) enddate
from cte2
where rn=1
group by Domain_Id, Starting_Date
order by Domain_Id, Starting_Date;
select * from Que_Date
This is the code that I have wrote but i am getting an extra row i.e 2nd row is extra, the expected output should have only 1st, 3rd and 4th row as output so please help me with it.
I have attached an image showing Input, Excepted Output, and the output that I am getting.
You've got so many results in your first cte. Your first cte has consisting domains. So you cannot filter domains based on your cte. So you query has unnecessary rows.
Try this solution. Cte ConsistentDomains has just consistent domains. So based on this cte, we can get not overlapped results.
Create and fill data:
CREATE TABLE FooTable
(
Domain_ID INT,
Starting_Date DATE,
End_Date Date
)
INSERT INTO dbo.FooTable
(
Domain_ID,
Starting_Date,
End_Date
)
VALUES
( 1, -- Domain_ID - int
CONVERT(datetime,'01-01-2011',103), -- Starting_Date - date
CONVERT(datetime,'05-01-2011',103) -- End_Date - date
)
, (1, CONVERT(datetime,'05-01-2011',103), CONVERT(datetime,'07-01-2011',103))
, (1, CONVERT(datetime,'07-01-2011',103), CONVERT(datetime,'15-01-2011',103))
, (2, CONVERT(datetime,'11-05-2011',103), CONVERT(datetime,'12-05-2011',103))
, (2, CONVERT(datetime,'13-05-2011',103), CONVERT(datetime,'14-05-2011',103))
Query to find not overlapping results:
DECLARE #startDate varchar(50) = '2011-01-01';
WITH ConsistentDomains AS
(
SELECT
f.Domain_ID
, f.Starting_Date
, f.End_Date
FROM FooTable f
WHERE f.Starting_Date = #startDate
UNION ALL
SELECT
s.Domain_ID
, s.Starting_Date
, s.End_Date
FROM FooTable s
INNER JOIN ConsistentDomains cd
ON s.Domain_ID = cd.Domain_ID
AND s.Starting_Date = cd.End_Date
), ConsistentDomainsRownumber AS
(
SELECT
cd.Domain_ID
, cd.Starting_Date
, cd.End_Date
, ROW_NUMBER() OVER (PARTITION BY cd.Domain_ID ORDER BY cd.Starting_Date,
cd.End_Date) RN
FROM ConsistentDomains cd
)
SELECT cd.Domain_ID
, convert(varchar, cd.Starting_Date, 105) Starting_Date
, convert(varchar, cd.End_Date, 105) End_Date
FROM ConsistentDomainsRownumber cd WHERE cd.RN = 1
UNION ALL
SELECT
ft.Domain_ID
, convert(varchar, ft.Starting_Date, 105) Starting_Date
, convert(varchar, ft.End_Date, 105) End_Date
FROM dbo.FooTable ft WHERE ft.Domain_ID NOT IN (SELECT cd.Domain_ID FROM
ConsistentDomainsRownumber cd)
Output:
I used the same table creating script as provided by #stepup, but you can also get your outcome in this way.
CREATE TABLE testtbl
(
Domain_ID INT,
Starting_Date DATE,
End_Date Date
)
INSERT INTO testtbl
VALUES
(1, convert(date, '01-01-2011' ,103), convert(date, '05-01-2011',103) )
,(1, convert(date, '05-01-2011' ,103), convert(date, '07-01-2011',103) )
,(1, convert(date, '07-01-2011' ,103), convert(date, '15-01-2011',103) )
,(2, convert(date, '11-05-2011' ,103), convert(date, '12-05-2011',103) )
,(2, convert(date, '13-05-2011' ,103), convert(date, '14-05-2011',103) )
You can make use of self join and Firs_value and last value within the group to make sure that you are comparing within the same ID and overlapping dates.
select distinct t.Domain_ID,
case when lag(t1.starting_date)over (partition by t.Domain_id order by
t.starting_date) is not null
then first_value(t.Starting_Date) over (partition by t.domain_id order by
t.starting_date)
else t.Starting_Date end StartingDate,
case when lead(t.domain_id) over (partition by t.domain_id order by t.starting_date) =
t1.Domain_ID then isnull(last_value(t.End_Date) over (partition by t.domain_id order by t.end_date rows between unbounded preceding and unbounded following),t.End_Date)
else t.End_Date end end_date
from testtbl t
left join testtbl t1 on t.Domain_ID = t1.Domain_ID
and t.End_Date = t1.Starting_Date
and t.Starting_Date < t1.Starting_Date
Output:
Domain_ID StartingDate end_date
1 2011-01-01 2011-01-15
2 2011-05-11 2011-05-12
2 2011-05-13 2011-05-14

Sum monthly amount and output for last day of month

I have table like example 1
here is summed amount by day. i need sum amount by month and join that value for last day of month, pls see image example 2
Thanks
Try this:
SELECT t.amount, t.dt, CASE WHEN month_cnt = rn THEN s ELSE NULL END AS month_s FROM (
select your_table.*,
sum(amount) over(partition by year(dt), month(dt) ) s,
count(*) over(partition by year(dt), month(dt)) month_cnt,
ROW_NUMBER() over(partition by year(dt), month(dt) order by dt) rn
from your_table
)t
order by dt
How about something like this?
create table #test
(
amount int,
trans date
)
insert into #test
SELECT
30, '2017-02-15'
UNION
SELECT
20, '2017-02-18'
UNION
SELECT
25, '2017-02-25'
UNION
SELECT
10, '2017-03-22'
UNION
SELECT
80, '2017-03-23'
UNION
SELECT
54, '2017-04-11'
SELECT
DATEPART(month, trans) month, SUM(amount) Sum
FROM
#test
GROUP BY
DATEPART(month, trans)

Group By Month and Year to get distinct month and years then combine as a single date SQL

SELECT CONVERT(DATE,CAST([Year] AS VARCHAR(4))+'-'+
CAST([Month] AS VARCHAR(2))+'-'+
CAST('1' AS VARCHAR(2))) Date
FROM (SELECT YEAR(Date) as [Year], MONTH(Date) as [Month] FROM [dbo].[Data]
GROUP BY YEAR(Date), MONTH(Date)) x
ORDER BY Date DESC
Is there a better way to doinq this with a single query?
The query should return the unique month and year from a table but as combined Date.
IF OBJECT_ID ('tempdb..#TempT') IS NOT NULL DROP TABLE #TempT
CREATE TABLE #TempT(
dt datetime)
INSERT INTO #TempT (dt) VALUES
('2016-10-11'),
('2016-10-3'),
('2016-9-13'),
('2016-9-16')
SELECT DISTINCT CAST(DATEADD(month, DATEDIFF(month, 0, dt), 0) as DATE) AS Dates
from #TempT
Sample data is really a necessity for these kinds of questions, but this function could also be a help for you DATEFROMPARTS
SELECT
DATEFROMPARTS([Year], [Month], 01)
FROM
(
SELECT
YEAR(Date) as [Year],
MONTH(Date) as [Month]
FROM [dbo].[Data]
GROUP BY YEAR(Date), MONTH(Date)
) x
ORDER BY Date DESC
This code takes whatever date you enter and evaluates it as the first of the month. Effectively looking at only month and year:
SELECT
DATEADD(MM,DATEDIFF(MM,0, [Date] ),0) AS [YearMonth]
FROM [dbo].[Data]
ORDER BY
DATEADD(MM,DATEDIFF(MM,0, [Date] ),0)
;

Performing 'UNION' on the queries with 'ORDER BY'

I am getting a syntax error at the Union all. I know I can't do this. But Can somebody help me out.
SELECT
ID,
date1,
date2 row_number() OVER (PARTITION BY ID ORDER BY date1 DESC ) as RN1,
1 as Range
FROM
(
SELECT ID,date1,
rn = row_number() OVER (PARTITION BY ID ORDER BY date1 )
FROM listing_History (nolock)
WHERE [date1] <= CONVERT(DATE,DATEADD(MONTH, -6, GETDATE())) AND
ID in (SELECT txt FROM [dbo].[fn_ListToTable](#listStr, ','))
) AS A ORDER BY date1 DESC, date2 DESC
UNION ALL
SELECT
ID,
Date1,
date2 row_number() OVER (PARTITION BY ID ORDER BY date1 DESC ) as RN1,
1 as Range
FROM
(
SELECT
ID,
date1,
rn = row_number() OVER (PARTITION BY ID ORDER BY date1 )
FROM listing_History (nolock)
WHERE [status_date] <= CONVERT(DATE,DATEADD(MONTH, -3, GETDATE()) -1)
AND
ID in (SELECT txt FROM [dbo].[fn_ListToTable](#listStr, ','))
) AS A ORDER BY date1 DESC,date2 desc
Remove all ORDER BYs from every UNION except the last one and make sure the column names you reference in the ORDER BY correspond to the first SELECT.
There should always one Order by on the very last select of UNION and UNION ALL
SELECT
ID,
date1,
date2 row_number() OVER (PARTITION BY ID ORDER BY date1 DESC ) as RN1,
1 as Range
FROM
(
SELECT ID,date1,
rn = row_number() OVER (PARTITION BY ID ORDER BY date1 )
FROM listing_History (nolock)
WHERE [date1] <= CONVERT(DATE,DATEADD(MONTH, -6, GETDATE()))
AND
ID in (SELECT txt FROM [dbo].[fn_ListToTable](#listStr, ','))
) AS A --ORDER BY date1 DESC, date2 DESC Remove order by from here
UNION ALL
SELECT
ID,
Date1,
date2 row_number() OVER (PARTITION BY ID ORDER BY date1 DESC ) as RN1,
1 as Range
FROM
(
SELECT ID,date1,
rn = row_number() OVER (PARTITION BY ID ORDER BY date1 )
FROM listing_History with(nolock)
WHERE [status_date] <= CONVERT(DATE,DATEADD(MONTH, -6, GETDATE()))
AND
ID in (SELECT txt FROM [dbo].[fn_ListToTable](#listStr, ','))
)AS A
ORDER BY date1 DESC, date2 DESC

Resources