I want to display the subtraction of the latest record in stage 2 and the latest record in stage 3 This is the table structure:
------------------------------------
name |stage| date
------------------------------------
| ABC | 2 | 2016-5-07
| ABC | 2 | 2016-6-08
| ABC | 3 | 2016-6-07
| ABC | 3 | 2016-12-08
| PQR | 2 | 2016-6-07
| PQR | 2 | 2016-8-12
| PQR | 3 | 2016-9-07
| PQR | 3 | 2016-10-08
I want to subtract date 2016-6-08 from date 2016-12-08 where name is ABC, they will be 183 days And subtract 2016-8-12 from 2016-10-08 where name is PQR
Output should be like as
| name | Date |
---------------
| ABC | 183 |
| PQR | 61 |
WITH cte AS (
SELECT t.[name], t.[stage], t.[date]
FROM
(
SELECT [name], [stage], [date],
ROW_NUMBER() OVER (PARTITION BY [name], [stage] ORDER BY [date] DESC) rn
) t
WHERE t.rn = 1
)
SELECT [name], DATEDIFF(day, MIN(t.[date]), MAX(t.[date])) AS [Date]
FROM cte t
GROUP BY [name]
SELECT [NAME], DATEDIFF(DAY, MIN(x.[DATE]), MAX(x.[DATE])) AS [DATE]
FROM
(SELECT T.[NAME], T.[STAGE], T.[DATE]
FROM
(
SELECT [NAME], [STAGE], [DATE],
ROW_NUMBER() OVER (PARTITION BY [NAME], [STAGE] ORDER BY [DATE] DESC) RN FROM #TABLE3
) T
WHERE T.RN = 1
)X
GROUP BY [NAME]
or
SELECT NAME, DATEDIFF(DD,MIN([DATE]),MAX([DATE])) AS [DATE] FROM
(SELECT NAME, STAGE, MAX([DATE]) AS [DATE] FROM #TABLE3 GROUP BY NAME, STAGE) C
GROUP BY NAME;
with cte as (
select name, stage, max([date]) as [date] from #YourTable group by name, stage
)
select name, datediff(dd,min([date]),max([date])) as [Date] from cte group by name;
The other answers are subtracting the minimum and maximum dates ignoring stage, instead of the max dates from each stage. Try this:
SELECT s2.name, DATEDIFF(day, MAX(s2.date), MAX(s3.date)) days
FROM MyTable s2 JOIN MyTable s3 ON s2.name = s3.name
WHERE s2.stage = 2 AND s3.stage = 3
GROUP BY s2.name;
The JOIN
combines two copies of the table into a single big table that has a row for every combination of two rows with the same name in the original table.
name | s2.stage | s2.date | s3.stage | s3.date
------+----------+------------+----------+------------
ABC | 2 | 2016-06-08 | 2 | 2016-06-08
ABC | 2 | 2016-06-08 | 3 | 2016-06-07
ABC | 2 | 2016-06-08 | 3 | 2016-12-08
ABC | 2 | 2016-06-08 | 2 | 2016-05-07
ABC | 3 | 2016-06-07 | 2 | 2016-06-08
ABC | 3 | 2016-06-07 | 3 | 2016-06-07
ABC | 3 | 2016-06-07 | 3 | 2016-12-08
ABC | 3 | 2016-06-07 | 2 | 2016-05-07
ABC | 3 | 2016-12-08 | 2 | 2016-06-08
ABC | 3 | 2016-12-08 | 3 | 2016-06-07
ABC | 3 | 2016-12-08 | 3 | 2016-12-08
ABC | 3 | 2016-12-08 | 2 | 2016-05-07
ABC | 2 | 2016-05-07 | 2 | 2016-06-08
ABC | 2 | 2016-05-07 | 3 | 2016-06-07
ABC | 2 | 2016-05-07 | 3 | 2016-12-08
ABC | 2 | 2016-05-07 | 2 | 2016-05-07
PQR | 2 | 2016-08-12 | 2 | 2016-08-12
PQR | 2 | 2016-08-12 | 3 | 2016-09-07
PQR | 2 | 2016-08-12 | 3 | 2016-10-08
PQR | 2 | 2016-08-12 | 2 | 2016-06-07
PQR | 3 | 2016-09-07 | 2 | 2016-08-12
PQR | 3 | 2016-09-07 | 3 | 2016-09-07
PQR | 3 | 2016-09-07 | 3 | 2016-10-08
PQR | 3 | 2016-09-07 | 2 | 2016-06-07
PQR | 3 | 2016-10-08 | 2 | 2016-08-12
PQR | 3 | 2016-10-08 | 3 | 2016-09-07
PQR | 3 | 2016-10-08 | 3 | 2016-10-08
PQR | 3 | 2016-10-08 | 2 | 2016-06-07
PQR | 2 | 2016-06-07 | 2 | 2016-08-12
PQR | 2 | 2016-06-07 | 3 | 2016-09-07
PQR | 2 | 2016-06-07 | 3 | 2016-10-08
PQR | 2 | 2016-06-07 | 2 | 2016-06-07
The WHERE s2.stage=2 AND s3.stage=3
restricts it to the rows where the s2 columns correspond to stage 2 and the s3 columns to stage 3:
name | s2.stage | s2.date | s3.stage | s3.date
------+----------+------------+----------+------------
ABC | 2 | 2016-05-07 | 3 | 2016-06-07
ABC | 2 | 2016-05-07 | 3 | 2016-12-08
ABC | 2 | 2016-06-08 | 3 | 2016-06-07
ABC | 2 | 2016-06-08 | 3 | 2016-12-08
PQR | 2 | 2016-06-07 | 3 | 2016-09-07
PQR | 2 | 2016-06-07 | 3 | 2016-10-08
PQR | 2 | 2016-08-12 | 3 | 2016-09-07
PQR | 2 | 2016-08-12 | 3 | 2016-10-08
We then take the maximum value of each date field for each name by using the MAX(...)
function and a GROUP BY name
clause, and subtract them using the DATEDIFF
function.
As a note, you should tag the question with the specific database you're using; the above SQL works in Microsoft SQL Server, but other databases do date difference differently and support a JOIN
... USING
syntax that would simplify the query slightly. For instance, this is what it would look like in Postgres:
SELECT name, MAX(s3.date) - MAX(s2.date) days
FROM MyTable s2 JOIN MyTable s3 USING (name)
WHERE s2.stage = 2 AND s3.stage = 3
GROUP BY name;
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.