I need to build a query to calculate the sum/total of a product_id, Product_Name fields based on Released_Date, revision_date, IS_UPDATED and display the output like the following. And I would appreciate if it shows the starting date and ending date instead of Week-1, Week-2.
Table structure and insert script as below.
create table products (
Released_Date varchar(40)
, product_id varchar(40)
, Product_Name varchar(40)
, revision_date varchar(40)
, IS_UPDATED varchar(2)
)
+-----------------+------------+-------------+--------------------------+---------------
insert into products values('2018-04-25 00:00:0','Pega','Pega5.0','2018-04-27 00:00:00','N');
insert into products values('2018-05-11 00:00:00','Oracle','orace11g','2018-05-13 00:00:00','Y');
insert into products values('2018-04-04 00:00:00','Oracle',' OracleBPM','2018-04-06 00:00:00','Y');
insert into products values('2018-06-05 00:00:00','Ibm','Cognos','2018-06-08 00:00:00','Y');
insert into products values('2018-05-03 00:00:00','Microsoft','C++','2018-05-05 00:00:00','Y');
insert into products values('2018-05-21 00:00:00','Microsoft',' C#','2018-05-25 00:00:00','Y');
insert into products values('2018-04-10 00:00:00','Salesforce','CPQ','2018-04-13 00:00:00','Y');
insert into products values('2018-03-12 00:00:00','Java',' Struts','2018-03-15 00:00:00','Y');
insert into products values('2018-04-12 00:00:00','Salesforce','Analytics','2018-04-13 00:00:00','Y');
insert into products values('2018-05-09 00:00:00','Microsoft','Asp','2018-05-11 00:00:00','Y');
insert into products values('2018-05-28 00:00:00','Salesforce','Marketing','2018-05-31 00:00:00','N');
insert into products values('2018-04-11 00:00:00','ETL',' Informatica','2018-04-12 00:00:00',' Y');
insert into products values('2018-03-26 00:00:00','Oracle',' orace11g','2018-03-30 00:00:00','Y');
insert into products values('2018-04-19 00:00:00','Oracle',' obiee','2018-04-20 00:00:00','Y');
insert into products values('2018-04-16 00:00:00','Ibm','Datastage','2018-04-17 00:00:00','N');
insert into products values('2018-06-18 00:00:00','Microsoft','C#','2018-06-21 00:00:00','Y');
insert into products values('2018-06-19 00:00:00','ETL',' Informatica','2018-06-24 00:00:00','Y');
insert into products values('2018-06-22 00:00:00','Microsoft','WCF','2018-06-23 00:00:00','Y');
insert into products values('2018-04-19 00:00:00','Hadoop',' Hive','2018-04-20 00:00:00',' Y');
insert into products values('2018-04-16 00:00:00','Testing','Database','2018-04-20 00:00:00','N');
insert into products values('2018-04-24 00:00:00','Ibm','Cognos',' 2018-04-27 00:00:00','Y');
insert into products values('2018-06-07 00:00:00','Microsoft','C#','2018-06-08 00:00:00','Y');
insert into products values('2018-04-02 00:00:00','Java','Struts','2018-04-05 00:00:00','Y');
insert into products values('2018-05-01 00:00:00','Microsoft','C++','2018-05-04 00:00:00','Y');
insert into products values('2018-04-10 00:00:00','ETL',' Datastage','2018-04-14 00:00:00','N');
insert into products values('2018-04-23 00:00:00','Ibm','AI','2018-04-25 00:00:00','Y');
insert into products values('2018-04-03 00:00:00','JAVA','Struts','2018-04-04 00:00:00','N');
insert into products values('2018-04-23 00:00:00','Pega','Pega5.4','2018-04-25 00:00:00','N');
insert into products values('2018-05-28 00:00:00','Java',' Jasperreports','2018-05-30 00:00:00','Y');
insert into products values('2018-05-28 00:00:00','IBM','Watson','2018-05-29 00:00:00','Y');
insert into products values('2018-05-30 00:00:00','Salesforce','Paradot','2018-05-31 00:00:00','Y');
insert into products values('2018-05-10 00:00:00','Oracle',' orace12c','2018-05-11 00:00:00','Y');
insert into products values('2018-06-11 00:00:00','Ibm','Cognos',' 2018-06-13 00:00:00','Y');
insert into products values('2018-06-13 00:00:00','Ibm','Datastage','2018-06-17 00:00:00','Y');
+-----------------+------------+-------------+--------------------------+---------------
Created_Date product_id Product_Name Released_Date IS_UPDATED
+-----------------+------------+---------------+--------------------------+---------------
2018-04-25 00:00:00 Pega Pega5.0 2018-04-27 00:00:00 N
2018-05-11 00:00:00 Oracle orace11g 2018-05-13 00:00:00 Y
2018-04-04 00:00:00 Oracle OracleBPM 2018-04-06 00:00:00 Y
2018-06-05 00:00:00 Ibm Cognos 2018-06-08 00:00:00 Y
2018-05-03 00:00:00 Microsoft C++ 2018-05-05 00:00:00 Y
2018-05-21 00:00:00 Microsoft C# 2018-05-25 00:00:00 Y
2018-04-10 00:00:00 Salesforce CPQ 2018-04-13 00:00:00 Y
2018-03-12 00:00:00 Java Struts 2018-03-15 00:00:00 Y
2018-04-12 00:00:00 Salesforce Analytics 2018-04-13 00:00:00 Y
2018-05-09 00:00:00 Microsoft Asp 2018-05-11 00:00:00 Y
2018-05-28 00:00:00 Salesforce Marketing 2018-05-31 00:00:00 N
2018-04-11 00:00:00 ETL Informatica 2018-04-12 00:00:00 Y
2018-03-26 00:00:00 Oracle orace11g 2018-03-30 00:00:00 Y
2018-04-19 00:00:00 Oracle obiee 2018-04-20 00:00:00 Y
2018-04-16 00:00:00 Ibm Datastage 2018-04-17 00:00:00 N
2018-06-18 00:00:00 Microsoft C# 2018-06-21 00:00:00 Y
2018-06-19 00:00:00 ETL Informatica 2018-06-24 00:00:00 Y
2018-06-22 00:00:00 Microsoft WCF 2018-06-23 00:00:00 Y
2018-04-19 00:00:00 Hadoop Hive 2018-04-20 00:00:00 Y
2018-04-16 00:00:00 Testing Database 2018-04-20 00:00:00 N
2018-04-24 00:00:00 Ibm Cognos 2018-04-27 00:00:00 Y
2018-06-07 00:00:00 Microsoft C# 2018-06-08 00:00:00 Y
2018-04-02 00:00:00 Java Struts 2018-04-05 00:00:00 Y
2018-05-01 00:00:00 Microsoft C++ 2018-05-04 00:00:00 Y
2018-04-10 00:00:00 ETL Datastage 2018-04-14 00:00:00 N
2018-04-23 00:00:00 Ibm AI 2018-04-25 00:00:00 Y
2018-04-03 00:00:00 JAVA Struts 2018-04-04 00:00:00 N
2018-04-23 00:00:00 Pega Pega5.4 2018-04-25 00:00:00 N
2018-05-28 00:00:00 Java Jasperreports 2018-05-30 00:00:00 Y
2018-05-28 00:00:00 IBM Watson 2018-05-29 00:00:00 Y
2018-05-30 00:00:00 Salesforce Paradot 2018-05-31 00:00:00 Y
2018-05-10 00:00:00 Oracle orace12c 2018-05-11 00:00:00 Y
2018-06-11 00:00:00 Ibm Cognos 2018-06-13 00:00:00 Y
2018-06-13 00:00:00 Ibm Datastage 2018-06-17 00:00:00 Y
Required output:-Based on below conditions.
for Total_productIds, the Created_Date should be greater than 2018-04-01 00:00:00 and Created_Date should be less than 2018-06-30 00:00:00.
i.e Created_Date>2018-04-01 00:00:00 and Created_Date<2018-06-30 00:00:00.
for Total_ProductNames, the Created_Date should be greater than 2018-04-01 00:00:00 and Released_Date should be revision_date<2018-06-30 00:00:00
Created_Date>2018-04-01 00:00:00 and Released_Date< 2018-06-30 00:00:00
for Total_IS_Updated, the Created_Date should be greater than 2018-04-01 00:00:00 and Created_Date should be less than 2018-06-30 00:00:00.
i.e Created_Date>2018-04-01 00:00:00 and Created_Date<2018-06-30 00:00:00. and
IS_UPDATED='Y'
WEEK NO. Total_productIds Total_ProductNames Total_IS_Updated(if 'Y')
Firstweek(2018-04-01) 0 0 0
Secondweek(2018-04-02 to 2018-04-08) 3 2 2
Thirdweek(2018-04-09 to 2018-04-15) 3 5 4
Fourthweek(2018-04-16 to 2018-04-22) 4 4 2
Fifthweek(2018-04-23 to 2018-04-29) 3 4 2
Firstweek(2018-05-01 to 2018-05-06) 1 2 2
Secondweek(2018-05-07 to 2018-05-13) 2 3 3
Thirdweek(2018-05-14 to 2018-05-20) 0 0 0
Fourthweek(2018-05-21 to 2018-05-27) 1 1 0
Fifthweek(2018-05-28 to 2018-05-31) 3 4 3
Firstweek(2018-06-01 to 2018-06-03) 0 0 0
Secondweek(2018-06-04 to 2018-06-10) 2 2 2
Thirdweek(2018-06-11 to 2018-06-17) 1 2 2
Fourthweek(2018-06-18 to 2018-06-24) 2 3 3
Fifthweek(2018-06-25 to 2018-06-30) 0 0 0
As you have mentioned interval conditions so I have hardcoded that. This query will fetch data and group it weekly.
I have replaced column format of week_no from Firstweek(2018-04-01) to week 1 of 04/2018 to make it fast.
SELECT week + DATEPART('wk', Created_Date) - DATEPART('wk', DATEADD(day, 1,
EOMONTH(Created_Date, - 1))) + 'of ' + DATEPART('mm', Created_Date) + '/' +
DATEPART('mm', Created_Date) as WEEK_NO, --- will result week 1 of 04/2018
sum(CASE
WHEN Created_Date > '2018-04-01 00:00:00'
AND Created_Date < '2018-06-30 00:00:00'
THEN 1
ELSE 0
END) AS Total_productIds, sum(CASE
WHEN Created_Date > '2018-04-01 00:00:00'
AND Released_Date < '2018-06-30 00:00:00'
THEN 1
ELSE 0
END) AS Total_ProductNames, sum(CASE
WHEN Created_Date > '2018-04-01 00:00:00'
AND Created_Date < '2018-06-30 00:00:00'
AND IS_UPDATED = 'Y'
THEN 1
ELSE 0
END) AS Total_ProductNames
FROM products
GROUP BY DATEPART('wk', Created_Date)
I have a query that looks at data that has been inserted into a TEMP table (not including as there is sensitive information in that table).
I can get the information I need, but I need to organize it better.
The output data displays as
trac_id CONTACT_DATE
040 2017-02-20 00:00:00.000
059 2017-03-08 00:00:00.000
001 2017-03-01 00:00:00.000
001 2017-03-08 00:00:00.000
001 2017-03-13 00:00:00.000
001 2017-03-16 00:00:00.000
001 2017-03-16 00:00:00.000
001 2017-03-17 00:00:00.000
001 2017-03-22 00:00:00.000
001 2017-03-23 00:00:00.000
001 2017-03-23 00:00:00.000
001 2017-03-24 00:00:00.000
001 2017-03-27 00:00:00.000
001 2017-03-27 00:00:00.000
001 2017-03-30 00:00:00.000
001 2017-03-31 00:00:00.000
068 2017-02-13 00:00:00.000
067 2017-01-24 00:00:00.000
060 2017-02-08 00:00:00.000
060 2017-03-07 00:00:00.000
011 2017-02-16 00:00:00.000
011 2017-03-01 00:00:00.000
011 2017-03-23 00:00:00.000
011 2017-03-30 00:00:00.000
005 2017-02-16 00:00:00.000
005 2017-03-18 00:00:00.000
005 2017-03-08 00:00:00.000
013 2017-03-08 00:00:00.000
013 2017-03-13 00:00:00.000
013 2017-03-16 00:00:00.000
013 2017-03-16 00:00:00.000
013 2017-03-17 00:00:00.000
013 2017-03-22 00:00:00.000
013 2017-03-23 00:00:00.000
013 2017-03-24 00:00:00.000
013 2017-03-27 00:00:00.000
013 2017-03-27 00:00:00.000
013 2017-03-30 00:00:00.000
013 2017-03-30 00:00:00.000
013 2017-03-31 00:00:00.000
043 2017-02-03 00:00:00.000
Right now I'm using the following query to get this:
SELECT
spl.trac_id
,pev.CONTACT_DATE
FROM
#SAMHSA_PAT_LIST spl
INNER JOIN dbo.IDENTITY_ID_VIEW iiv
ON iiv.IDENTITY_ID=spl.MRN
LEFT JOIN dbo.PAT_ENC_VIEW pev
ON pev.PAT_ID = iiv.PAT_ID
LEFT JOIN dbo.PAT_ENC_RSN_VISIT_VIEW rsn
ON rsn.PAT_ENC_CSN_ID=pev.PAT_ENC_CSN_ID
WHERE
pev.CONTACT_DATE >= #Start_Date
AND pev.CONTACT_DATE < #End_Date
AND pev.APPT_STATUS_C IN ( 2 , 6 , 8 , 9 )
AND rsn.ENC_REASON_ID = 590;
What I need to get is to have 2+n columns. I won't know exactly how many but a quick look shows trac_id 001 with 14 entries. So if that was the max number I would need the columns to be trac_id, mm_1, mm_2, mm_3, mm_4,...,mm_14 without hard coding the number of columns I want to PIVOT into. My problem is that in all of the posts and documentation I've seen about using PIVOT I see the data inserted into a table beforehand and then usually the entire table is PIVOT'ed.
Is it possible to only PIVOT the second column and if so, how would I do this?
So, I was able to figure out part of my solution based on a couple posts and your help #Jakub_Ojmucianski. What I've come up with is the following, but it's only halfway there and I'm sure I've made a mistake:
DECLARE #SQL VARCHAR(MAX)='',#PVT_COL VARCHAR(MAX)='';
SELECT #PVT_COL =#PVT_COL + '[mm_'+CAST(ROW_NUMBER() OVER(ORDER BY (SELECT
1)) AS VARCHAR(4))+'],'
FROM #medmtemp
SELECT #PVT_COL = LEFT(#PVT_COL,LEN(#PVT_COL)-1)
SELECT #SQL =
'SELECT * FROM (
SELECT trac_id, Contact ,''mm_''+CAST(ROW_NUMBER() OVER(ORDER BY (SELECT 1))
AS VARCHAR(4)) AS COL_NME
FROM #medmtemp
)AS A
PIVOT
(
MAX(Contact) FOR COL_NME IN ('+#PVT_COL+')
)PVT'
EXEC (#SQL)
I see the following (Just including the first three new rows):
trac_id mm_1 mm_2 mm_3 mm_4 mm_5 mm_6 mm_7 mm_8 mm_9 mm_10 mm_11 mm_12 mm_13 mm_14 mm_15 mm_16 mm_17 mm_18 mm_19 mm_20
1 3/1/2017 3/8/2017 3/13/2017 3/16/2017 3/16/2017 3/17/2017 3/22/2017 3/23/2017 3/23/2017 3/24/2017 3/27/2017 3/27/2017 3/30/2017 3/31/2017 NULL NULL NULL NULL NULL NULL
5 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 2/16/2017 3/18/2017 3/8/2017 NULL NULL NULL
8 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 3/8/2017 3/23/2017 3/30/2017
you can do something like that:
IF(OBJECT_ID('tempdb..#myTable') IS NOT null)
DROP TABLE #myTable
IF(OBJECT_ID('tempdb..#pivotColumn') IS NOT null)
DROP TABLE #pivotColumn
CREATE TABLE #myTable
(
trac_id varchar(3),
CONTACT_DATE datetime
)
INSERT INTO #myTable VALUES
('040', '2017-02-20 00:00:00.000'),
('059' ,'2017-03-08 00:00:00.000'),
('001' ,'2017-03-01 00:00:00.000'),
('001' ,'2017-03-08 00:00:00.000'),
('001' ,'2017-03-13 00:00:00.000'),
('001' ,'2017-03-16 00:00:00.000'),
('001' ,'2017-03-17 00:00:00.000')
SELECT ROW_NUMBER() OVER(ORDER BY CONTACT_DATE) as rowNumber,CONTACT_DATE INTO #pivotColumn FROM(
SELECT DISTINCT CONTACT_DATE FROM #myTable
) AS source
DECLARE #columns VARCHAR(MAX)=''
DECLARE #curentRow int = 1;
WHILE #curentRow <= (SELECT MAX(rowNumber) from #pivotColumn)
BEGIN
SET #columns+= '['+(SELECT Cast(CONTACT_DATE as varchar) FROM #pivotColumn WHERE rowNumber = #curentRow)+'],'
SET #curentRow += 1;
END
SET #columns = SUBSTRING(#columns,1,LEN(#columns)-1)
DECLARE #code Varchar(MAX) =
'
SELECT * FROM #myTable
Pivot
(
COUNT(trac_id) FOR CONTACT_DATE IN (
'
+
#columns
+
'
)
) as p'
EXEC(#code)
But be aware of grouping function in dynamic pivot - you have to decide what you want to do with those data? Sum it, count it?
Regards
Example data:
FK_EmployeeId FromDate ToDate DateDiff
20325 2016-06-24 00:00:00.000 2016-06-25 00:00:00.000 2
20325 2016-06-25 00:00:00.000 2016-06-26 00:00:00.000 2
20325 2016-06-26 00:00:00.000 2016-06-28 00:00:00.000 3
20325 2016-06-28 00:00:00.000 2016-06-29 00:00:00.000 2
20325 2016-06-29 00:00:00.000 2016-06-30 00:00:00.000 2
20325 2016-06-30 00:00:00.000 2016-07-01 00:00:00.000 2
20325 2016-07-01 00:00:00.000 2016-07-02 00:00:00.000 2
20325 2016-07-02 00:00:00.000 2016-07-03 00:00:00.000 2
20325 2016-07-03 00:00:00.000 2016-07-04 00:00:00.000 2
20325 2016-07-04 00:00:00.000 2016-07-05 00:00:00.000 2
And I would like to get the following output:
FK_EmployeeId FromDate ToDate DateDiff
20325 2016-06-24 00:00:00.000 2016-06-26 00:00:00.000 3
20325 2016-06-28 00:00:00.000 2016-07-05 00:00:00.000 8
I think you are trying to do something like the below using a windowing function to join the records to themselves to perform the date comparisons across 2 rows.
However as people have already suggested in the comments your sample data above contains all sequential dates so its not really clear how your expecting this to work. I've therefore excluded a middle value in the sample data to demonstrate the approach.
--TABLE JUST FOR EXAMPLE QUERY
DECLARE #SomeTable TABLE ([FK_EmployeeId] INT,[FromDate] DATETIME,[ToDate] DATETIME,[DateDiff] INT)
--YOUR SAMPLE DATA
INSERT INTO #SomeTable
([FK_EmployeeId],[FromDate],[ToDate],[DateDiff])
SELECT 20325,'2016-06-24 00:00:00.000','2016-06-25 00:00:00.000',2
UNION SELECT 20325,'2016-06-25 00:00:00.000','2016-06-26 00:00:00.000',2
UNION SELECT 20325,'2016-06-26 00:00:00.000','2016-06-28 00:00:00.000',3
UNION SELECT 20325,'2016-06-28 00:00:00.000','2016-06-29 00:00:00.000',2
UNION SELECT 20325,'2016-06-29 00:00:00.000','2016-06-30 00:00:00.000',2
--UNION SELECT 20325,'2016-06-30 00:00:00.000','2016-07-01 00:00:00.000',2 --<<
UNION SELECT 20325,'2016-07-01 00:00:00.000','2016-07-02 00:00:00.000',2
UNION SELECT 20325,'2016-07-02 00:00:00.000','2016-07-03 00:00:00.000',2
UNION SELECT 20325,'2016-07-03 00:00:00.000','2016-07-04 00:00:00.000',2
UNION SELECT 20325,'2016-07-04 00:00:00.000','2016-07-05 00:00:00.000',2
--THE POINT:
;WITH cte AS
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY [FK_EmployeeId] ORDER BY [ToDate]) AS 'RowNo'
FROM
#SomeTable
)
SELECT
a.*,
DATEDIFF(DAY,a.[FromDate],b.[ToDate]) AS 'NewDiff'
FROM
cte a
JOIN cte b
ON a.[RowNo] + 1 = b.[RowNo]
WHERE
a.[ToDate] <> b.[FromDate]
A little more detail in the question next time please.
I have the following SQL Server query problem.
If there is a row where Issue_DATE = as Maturity_Date in another row, and if both rows have the same ID and Amount USD, then none of these rows should be displayed.
Here is a simplified version of my table:
ID ISSUE_DATE MATURITY_DATE AMOUNT_USD
1 2010-01-01 00:00:00.000 2015-12-01 00:00:00.000 5000
1 2010-01-01 00:00:00.000 2001-09-19 00:00:00.000 700
2 2014-04-09 00:00:00.000 2019-04-09 00:00:00.000 400
1 2015-12-01 00:00:00.000 2016-12-31 00:00:00.000 5000
5 2015-02-24 00:00:00.000 2015-02-24 00:00:00.000 8000
4 2012-11-29 00:00:00.000 2015-11-29 00:00:00.000 10000
3 2015-01-21 00:00:00.000 2018-01-21 00:00:00.000 17500
2 2015-02-02 00:00:00.000 2015-12-05 00:00:00.000 12000
1 2015-01-12 00:00:00.000 2018-01-12 00:00:00.000 18000
2 2015-12-05 00:00:00.000 2016-01-10 00:00:00.000 12000
Result should be:
ID ISSUE_DATE MATURITY_DATE AMOUNT_USD
1 2010-01-01 00:00:00.000 2001-09-19 00:00:00.000 700
2 2014-04-09 00:00:00.000 2019-04-09 00:00:00.000 400
5 2015-02-24 00:00:00.000 2015-02-24 00:00:00.000 8000
4 2012-11-29 00:00:00.000 2015-11-29 00:00:00.000 10000
3 2015-01-21 00:00:00.000 2018-01-21 00:00:00.000 17500
1 2015-01-12 00:00:00.000 2018-01-12 00:00:00.000 18000
I tried with self join, but I do not get right result.
Thanks in advance!
Can you try something like this? 'not exists' is the way of doing it.
select * from table t1 where not exists (select 'x' from table t2 where t1.issue_date = t2.maturity_date and t1.amount_usd=t2.amount_usd and t1.id = t2.id)
I'd think about making subquery of all the dupes and then eliminating them from the first table like so:
select t1.ID
, t1.ISSUE_DATE
, t1.MATURITY_DATE
, t1.AMOUNT_USD
FROM
t1
LEFT JOIN
(select a.ID
, a.ISSUE_DATE
, a.MATURITY_DATE
, a.AMOUNT_USD
FROM
t1 a
INNER JOIN
ti b
) dupes
on
t1.ID = dupes.ID
WHERE dupes.ID IS NULL;
There is a table test that contains data as shown below:
id id1 id2 id3 date1
1 1 2 2500 2010-09-30 00:00:00.000
2 1 2 4700 2005-01-01 00:00:00.000
3 1 2 4700 2009-08-01 00:00:00.000
4 1 3 2500 2010-09-30 00:00:00.000
5 1 3 4700 2003-02-01 00:00:00.000
6 1 8 4000 2007-04-01 00:00:00.000
7 1 8 4000 2013-09-01 00:00:00.000
8 1 8 4060 2007-04-01 00:00:00.000
9 1 8 8500 2010-09-30 00:00:00.000
What I need to do is order this data in the following format:
id1 id2 id3 date1 date2
1 2 2500 2010-09-30 00:00:00.000 9999-12-31 23:59:59.997
1 2 4700 2005-01-01 00:00:00.000 2009-07-31 00:00:00.000
1 2 4700 2009-08-01 00:00:00.000 9999-12-31 23:59:59.997
1 3 2500 2010-09-30 00:00:00.000 9999-12-31 23:59:59.997
1 3 4700 2003-02-01 00:00:00.000 9999-12-31 23:59:59.997
1 8 4000 2007-04-01 00:00:00.000 2013-08-31 00:00:00.000
1 8 4000 2013-09-01 00:00:00.000 9999-12-31 23:59:59.997
1 8 4060 2007-04-01 00:00:00.000 9999-12-31 23:59:59.997
1 8 8500 2010-09-30 00:00:00.000 9999-12-31 23:59:59.997
Using the following logic:
If there is only one record for the same id1, id2 and id3 we use the original date for date1 and we use the maximum date available in sql server (9999-12-31) for date2.
If there is more than one record for the same id1, id2 and id3 we still keep the original date for date1 and we use for date2 the original date field minus 1 day from the next record . The last record will use also the maximum date available in sql server (9999-12-31) for date2.
I manage to build the following query but it is not perfect as it brings some invalid records:
select * from
(select
t1.id1,t1.id2,t1.id3,t1.date1,
case
when t1.date1=t2.date1 then CONVERT(DATETIME, '12/31/9999 23:59:59.997')
else DATEADD(day, -1, t2.date1)
end as date2
from test t1
inner join test t2
on t1.id1=t2.id1 and t1.id2=t2.id2 and t1.id3=t2.id3
) sub
where date2>=date1
order by id1,id2,id3,date1 asc
The result of the query is:
id1 id2 id3 date1 date2
1 2 2500 2010-09-30 00:00:00.000 9999-12-31 23:59:59.997
1 2 4700 2005-01-01 00:00:00.000 9999-12-31 23:59:59.997 *
1 2 4700 2005-01-01 00:00:00.000 2009-07-31 00:00:00.000
1 2 4700 2009-08-01 00:00:00.000 9999-12-31 23:59:59.997
1 3 2500 2010-09-30 00:00:00.000 9999-12-31 23:59:59.997
1 3 4700 2003-02-01 00:00:00.000 9999-12-31 23:59:59.997
1 8 4000 2007-04-01 00:00:00.000 9999-12-31 23:59:59.997 *
1 8 4000 2007-04-01 00:00:00.000 2013-08-31 00:00:00.000
1 8 4000 2013-09-01 00:00:00.000 9999-12-31 23:59:59.997
1 8 4060 2007-04-01 00:00:00.000 9999-12-31 23:59:59.997
1 8 8500 2010-09-30 00:00:00.000 9999-12-31 23:59:59.997
As you can see, the records marked with * are not necessary but I don't know how to get rid off that rows.
This should do:
select id1,id2,id3, date1,
isnull(lead(date1) over(partition by id1,id2,id3 order by date1)-1, '99991231') as date2
from test
Try something like this
SELECT t1.id1, t1.id2, t1.id3, t1.date1 as date1,
ISNULL(t2.date1, CONVERT(DATETIME, '12/31/9999 23:59:59.997')) as date2
FROM test t1
LEFT JOIN test t2 ON t1.id1 = t2.id1 AND t1.id2 = t2.id2 AND t1.id3 = t2.id3
AND t1.id < t2.id
ORDER BY t1.id1, t1.id2, t1.id3, date1, date2