Consider the following schema:
CREATE TABLE `Result` (
`startDate` date NOT NULL,
`description` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
`value` decimal(15,4) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `Result`
(`startDate`,
`description`,
`value`)
VALUES
('2020-09-01' ,'Allowance' ,4000),
('2020-09-01' ,'Salary' ,1500),
('2020-10-01' ,'Allowance' ,2000),
('2020-10-01' ,'Salary' ,3000),
('2020-10-01' ,'Deduction' ,-200);
Given a date,the result should show as the total for a description & startdate and the difference between the date selected and previous date(month). So if October was the month selected the result of the query should show as,
description SeptemberTotal OctoberTotal Variance
Allowance 4000 2000 -2000
Salary 1500 3000 1500
Deduction 0 -200 -200
My attempt using a union & a pivot,
SELECT #selectDate:='2020-10-01'; -- set desired date
SELECT
t.month,
t.description,
Gross,
from (
SELECT
DATE_FORMAT(pi.startDate, '%b/%y') AS 'Month',
SUM(pi.value) AS gross,
description
FROM
Result pi
WHERE
pi.startDate = DATE_SUB(#selectDate, INTERVAL 1 MONTH) -- select previous month
GROUP BY description
UNION SELECT
DATE_FORMAT(pi.startDate, '%b/%y') AS 'Month',
SUM(pi.value) AS gross,
description
FROM
Result pi
WHERE
pi.startDate = #selectDate
GROUP BY description) t
GROUP BY t.Month,t.description
;
which gives the result as,
Month description Gross
Sep/20 Allowance 4000
Sep/20 Salary 1500
Oct/20 Allowance 2000
Oct/20 Salary 3000
Oct/20 Deduction -200
which is not exactly what the requirement is. I have tried a pivot query as well, that too is not showing the output as required.
db-fiddle
SET #m1 := '2020-09-01';
SET #m2 := '2020-10-01';
SELECT Result.Description,
COALESCE(SUM(CASE WHEN Result.startDate = #m1 THEN value END), 0) Total1,
COALESCE(SUM(CASE WHEN Result.startDate = #m2 THEN value END), 0) Total2,
COALESCE(SUM(CASE WHEN Result.startDate = #m2 THEN value END), 0) -
COALESCE(SUM(CASE WHEN Result.startDate = #m1 THEN value END), 0) Variance
FROM ( SELECT #m1 startDate UNION ALL SELECT #m2 ) baseDates
LEFT JOIN Result USING (startDate)
GROUP BY Result.Description
fiddle
select
description,
sum(if(startDate between '2020-11-01 00:00:00' and '2020-11-31 23:59:59' ,value,0)) 1st,
sum(if(startDate between '2020-12-01 00:00:00' and '2020-12-31 23:59:59',value,0)) 2nd,
sum(if(startDate between '2020-11-01 00:00:00' and '2020-11-31 23:59:59' ,value,0))-sum(if(created_at between '2020-12-01 00:00:00' and '2020-12-31 23:59:59',value,0)) Variance
from
Result
where startDate between '2020-11-01 00:00:00' and '2020-12-31 23:59:59' group by description
Related
From this table of dates and categories inputs :
I'd like to get these folowing table, showing number of rows per category for each first and second quarter, and the growth of number of rows between second and first quarter, in value, and in percentage - which is a simple statistic table type that could be met to get the number of item per period of time and its growth.
What would be the sql query to get this table ?
Here is the SQL code to create the sql table, in order you to reproduce the schema:
CREATE TABLE `table_a_test_table` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`date_row` timestamp NULL DEFAULT NULL,
`category` varchar(255) NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
Here is the sql code to fill the table with the data :
INSERT INTO `table_a_test_table` (`date_row`, `category`)
VALUES
('2020-01-03 00:00:00', 'A'),
('2020-02-02 00:00:00', 'A'),
('2020-03-08 00:00:00', 'B'),
('2020-02-06 00:00:00', 'C'),
('2020-04-07 00:00:00', 'B'),
('2020-05-21 00:00:00', 'A'),
('2020-06-07 00:00:00', 'C'),
('2020-06-08 00:00:00', 'B')
;
I've tried the following sql code, to get the result table, but I do not know where I should, and how I should introduce the category field in order to get a group by output.
SELECT
nb_rows_q1.nb_of_rows AS `number of row in q1`,
nb_rows_q2.nb_of_rows AS `number of row in q2`,
((nb_rows_q2.nb_of_rows - nb_rows_q1.nb_of_rows)/nb_rows_q1.nb_of_rows)*100 AS `growth nb of rows between q2 vs q1`
FROM
(
SELECT COUNT(id) AS nb_of_rows
FROM table_a_test_table
WHERE
date_row >= '2020-01-01 00:00:00'
AND date_row < '2020-04-01 00:00:00'
) AS nb_rows_q1,
(
SELECT COUNT(id) AS nb_of_rows
FROM table_a_test_table
WHERE
date_row >= '2020-04-01 00:00:00'
AND date_row < '2020-07-01 00:00:00'
) AS nb_rows_q2
;
The above code, returns the following :
So now, I'd like t place the category field into the code. But I do not knwo how to do it.
Any idea ?
You would need to aggregate by categories within your subqueries first so you wouldn't lose the category details in the final projection. See a sample working fiddle and results below:
CREATE TABLE `table_a_test_table` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`date_row` timestamp NULL DEFAULT NULL,
`category` varchar(255) NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
INSERT INTO `table_a_test_table` (`date_row`, `category`)
VALUES
('2020-01-03 00:00:00', 'A'),
('2020-02-02 00:00:00', 'A'),
('2020-03-08 00:00:00', 'B'),
('2020-02-06 00:00:00', 'C'),
('2020-04-07 00:00:00', 'B'),
('2020-05-21 00:00:00', 'A'),
('2020-06-07 00:00:00', 'C'),
('2020-06-08 00:00:00', 'B')
;
Query #1
SELECT
nb_rows_q1.category,
nb_rows_q1.nb_of_rows AS `number of row in q1`,
nb_rows_q2.nb_of_rows AS `number of row in q2`,
(nb_rows_q2.nb_of_rows - nb_rows_q1.nb_of_rows) as `variation of nb of row q2 vs q1`,
((nb_rows_q2.nb_of_rows - nb_rows_q1.nb_of_rows)/nb_rows_q1.nb_of_rows)*100 AS `growth nb of rows between q2 vs q1`
FROM
(
SELECT category, COUNT(id) AS nb_of_rows
FROM table_a_test_table
WHERE
date_row >= '2020-01-01 00:00:00'
AND date_row < '2020-04-01 00:00:00'
GROUP BY category
) AS nb_rows_q1
INNER JOIN
(
SELECT category,COUNT(id) AS nb_of_rows
FROM table_a_test_table
WHERE
date_row >= '2020-04-01 00:00:00'
AND date_row < '2020-07-01 00:00:00'
GROUP BY category
) AS nb_rows_q2 ON nb_rows_q1.category = nb_rows_q2.category
;
category
number of row in q1
number of row in q2
variation of nb of row q2 vs q1
growth nb of rows between q2 vs q1
A
2
1
-1
-50.0000
B
1
2
1
100.0000
C
1
1
0
0.0000
View on DB Fiddle
Update 1
Another approach has been included below where the aggregation has been done with the help of a case expression. I have also added to your test data, D only in q2, E only in q1 and F neither in q1 or q2. This approach includes categories in either quarter. I also added a case expression for categories that are new or only occurring in quarter 2 that would have the growth rate as null. This is up to you whether you would like the growth rate returned as null or a default value, I included 100
CREATE TABLE `table_a_test_table` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`date_row` timestamp NULL DEFAULT NULL,
`category` varchar(255) NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
INSERT INTO `table_a_test_table` (`date_row`, `category`)
VALUES
('2020-01-03 00:00:00', 'A'),
('2020-02-02 00:00:00', 'A'),
('2020-03-08 00:00:00', 'B'),
('2020-02-06 00:00:00', 'C'),
('2020-04-07 00:00:00', 'B'),
('2020-05-21 00:00:00', 'A'),
('2020-06-07 00:00:00', 'C'),
('2020-06-08 00:00:00', 'B'),
('2020-06-08 00:00:00', 'D'),
('2020-01-03 00:00:00', 'E'),
('2019-01-03 00:00:00', 'F')
;
Query #1
SELECT
category,
q1 as `number of row in q1`,
q2 as `number of row in q2`,
(q2 - q1) as `variation of nb of row q2 vs q1`,
CASE
WHEN q1=0 THEN 100.0
ELSE((q2-q1)/q1)*100
END as `growth nb of rows between q2 vs q1`
FROM (
SELECT
category,
SUM(CASE WHEN date_row < '2020-04-01 00:00:00' THEN 1 ELSE 0 END ) as q1,
SUM(CASE WHEN date_row >= '2020-04-01 00:00:00' THEN 1 ELSE 0 END ) as q2
FROM
table_a_test_table
WHERE
date_row BETWEEN '2020-01-01 00:00:00' AND '2020-07-01 00:00:00'
GROUP BY
category
) summary;
category
number of row in q1
number of row in q2
variation of nb of row q2 vs q1
growth nb of rows between q2 vs q1
A
2
1
-1
-50.0000
B
1
2
1
100.0000
C
1
1
0
0.0000
D
0
1
1
100.0
E
1
0
-1
-100.0000
View on DB Fiddle
Feel free to experiment with other filtering options. For example, if you would like to filter out entries like D or E that exist in only one quarter you may consider adding a WHERE clause similar to WHERE q1 > 0 and q2 > 0; as shown below:
SELECT
category,
q1 as `number of row in q1`,
q2 as `number of row in q2`,
(q2 - q1) as `variation of nb of row q2 vs q1`,
CASE
WHEN q1=0 THEN 100.0
ELSE((q2-q1)/q1)*100
END as `growth nb of rows between q2 vs q1`
FROM (
SELECT
category,
SUM(CASE WHEN date_row < '2020-04-01 00:00:00' THEN 1 ELSE 0 END ) as q1,
SUM(CASE WHEN date_row >= '2020-04-01 00:00:00' THEN 1 ELSE 0 END ) as q2
FROM
table_a_test_table
WHERE
date_row BETWEEN '2020-01-01 00:00:00' AND '2020-07-01 00:00:00'
GROUP BY
category
) summary
WHERE q1 > 0 and q2 > 0;
category
number of row in q1
number of row in q2
variation of nb of row q2 vs q1
growth nb of rows between q2 vs q1
A
2
1
-1
-50.0000
B
1
2
1
100.0000
C
1
1
0
0.0000
View on DB Fiddle
I hope this helps.
You probably just need one subquery and don't need JOIN at all. Something like this:
SELECT category,
q1 AS `number of row in q1`,
q2 AS `number of row in q2`,
q2-q1 AS `variation of nb of q2 vs q1`,
((q2-q1)/q1)*100 AS `growth nb of rows between q2 vs q1`
FROM
(SELECT category,
SUM(CASE WHEN date_row >= '2020-01-01 00:00:00'
AND date_row < '2020-04-01 00:00:00'
THEN 1 ELSE 0 END) AS 'q1',
SUM(CASE WHEN date_row >= '2020-04-01 00:00:00'
AND date_row < '2020-07-01 00:00:00'
THEN 1 ELSE 0 END) AS 'q2'
FROM table_a_test_table
GROUP BY category) A;
The base query there I use SUM() with CASE expression. The condition in both of your previous subqueries I used as the condition in the CASE expression followed by a GROUP BY on category column. And as you can see, I've assigned with short abbreviations for q1 and q2 and instead of doing all the calculation for differences and percentage in the same line of SELECT, I turned the query into a subquery and do the calculation outside. This, in my opinion, made the query much more readable.
Demo fiddle
I have a table (test_matches) with a record of the results of several games, sorted by date.
GHFT = Goals Home Team Full Time.
GAFT = Goals Away Team Full Time.
CREATE TABLE `test_matches` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`match_date` date NOT NULL,
`home_team` varchar(250) DEFAULT NULL,
`away_team` varchar(250) DEFAULT NULL,
GHFT` int(11) NOT NULL DEFAULT '0',
`GAFT` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
);
INSERT INTO test_matches (match_date, home_team, away_team, GHFT, GAFT )
VALUES ('2019-01-01', 'Real Madrid', 'Zaragoza', 2,0),
('2019-01-03', 'Barcelona', 'Lugo', 1,1),
('2019-01-04', 'Real Madrid', 'Lugo', 2,1),
('2019-01-05', 'Barcelona', 'Compostela', 4,1),
('2019-01-06', 'Real Madrid', 'Barcelona', 0,2),
('2019-01-07', 'Barcelona', 'Zaragoza', 0,0);
http://sqlfiddle.com/#!9/c0f16a/1
I tried this query:
SELECT home_team,
ROUND(SUM(CASE WHEN ghft > gaft = 1 THEN 1 ELSE 0 END) /COUNT(*) *100) AS W_Home_Team,
ROUND(SUM(CASE WHEN ghft = gaft = 1 THEN 1 ELSE 0 END) /COUNT(*) *100) AS D_Home_Team,
ROUND(SUM(CASE WHEN ghft < gaft = 1 THEN 1 ELSE 0 END) /COUNT(*) *100) AS L_Home_Team
FROM ( SELECT home_team, ghft, gaft FROM test_matches ORDER BY id DESC LIMIT 2) average
GROUP BY home_team;
However, the result I get is not correct, since it is taking into account the last two records of the table, not the last two records of each team.
The correct result is:
Barcelona 50-50-0 and Real Madrid 50-0-50.
How can I calculate the percentages of the last 2 matches of each team?
With this SELECT Statement
SELECT
home_team
, ROUND(SUM(IF(ghft > gaft,1,0)) / COUNT(*),2) * 100 W_Home_Team
, ROUND(SUM(IF(ghft = gaft,1,0)) / COUNT(*),2) * 100 D_Home_Team
, ROUND(SUM(IF(ghft < gaft,1,0)) / COUNT(*),2) * 100 L_Home_Team
FROM
(SELECT
home_team
,match_date
, ghft
, gaft
, IF(#team <> home_team,#rank := 0, #rank := #rank) dec1
,#rank := #rank+1 rnk
,#team := home_team
FROM test_matches,(SELECT #rank := 0) r1,(SELECT #team := '') r2
ORDER BY home_team,match_date) t1
WHERE rnk < 3
GROUP BY home_team
;
You get this result
home_team W_Home_Team D_Home_Team L_Home_Team
Barcelona 50 50 0
Real Madrid 100 0 0
This rounds the division to two digit so that you will get 25,25 Procent. You will have to adept this to your needs.
The inner SELECT is only to get the correct number of games per club.
with WHERE rnk < 3 you can change the number of games you need
SQL Fiddle example
I am using MySQL database. I have employee leave table which having information about employee leave.
Please find table details:
CREATE TABLE IF NOT EXISTS `APPLY_LEAVE` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`EMP_ID` varchar(100) NOT NULL,
`TYPE_OF_LEAVE` varchar(100) NOT NULL,
`DAYS` varchar(100) NOT NULL,
`REASON` varchar(200) NOT NULL,
`START_DATE` date NOT NULL,
`END_DATE` date NOT NULL,
`STATUS` tinyint(2) NOT NULL,
`CREATED_ON` date NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;
--
-- Dumping data for table `APPLY_LEAVE`
--
INSERT INTO `APPLY_LEAVE` (`ID`, `EMP_ID`, `TYPE_OF_LEAVE`, `DAYS`, `REASON`, `START_DATE`, `END_DATE`, `STATUS`, `CREATED_ON`) VALUES
(1, 'EMP001', 'SL', '2', 'Sick Leave', '2018-11-30', '2018-12-01', 1,'2018-11-06'),
(2, 'EMP002', 'EL', '1', 'Personal', '2018-12-13', '2018-12-13', 1,'2018-11-09'),
(3, 'EMP003', 'CL', '2', 'Casual Leave due to Birthday', '2018-08-31', '2018-09-01', 1,'2018-08-20'),
(4, 'EMP001', 'CL', '3', 'Casual Leave', '2018-12-04', '2018-12-06', 1,'2018-11-27'),
(5, 'EMP002', 'SL', '4', 'Sick Leave', '2018-09-10', '2018-09-13', 1,'2018-10-04'),
(6, 'EMP003', 'SL', '3', 'Sick Leave', '2018-10-30', '2018-11-01', 1,'2018-11-25');
Require Output:
I want to generate Report/excel to receive information as month wise employee leave data based on leave type i.e (Month wise, Leave type data)
Format should be below:
Requirement: I want MySQL query to fetch attached result month wise, Leave type data(SL/CL/EL) which took by Employee.
Query tries:
SELECT EMP_ID,
SUM(CASE WHEN TYPE_OF_LEAVE = 'EL' AND MONTH( START_DATE ) =11 THEN DAYS ELSE 0 END ) AS EL_NOV,
SUM(CASE WHEN TYPE_OF_LEAVE = 'CL' AND MONTH( START_DATE ) =11 THEN DAYS ELSE 0 END ) AS CL_NOV,
SUM(CASE WHEN TYPE_OF_LEAVE = 'SL' AND MONTH( START_DATE ) =11 THEN DAYS ELSE 0 END ) AS SL_NOV,
SUM(CASE WHEN TYPE_OF_LEAVE = 'LOP' AND MONTH( START_DATE ) =11 THEN DAYS ELSE 0 END ) AS LOP_NOV,
SUM(CASE WHEN TYPE_OF_LEAVE = 'EL' AND MONTH( START_DATE ) =12 THEN DAYS ELSE 0 END ) AS EL_DEC,
SUM(CASE WHEN TYPE_OF_LEAVE = 'CL' AND MONTH( START_DATE ) =12 THEN DAYS ELSE 0 END ) AS CL_DEC,
SUM(CASE WHEN TYPE_OF_LEAVE = 'SL' AND MONTH( START_DATE ) =12 THEN DAYS ELSE 0 END ) AS SL_DEC,
SUM(CASE WHEN TYPE_OF_LEAVE = 'LOP' AND MONTH( START_DATE ) =12 THEN DAYS ELSE 0 END ) AS LOP_DEC
FROM APPLY_LEAVE
GROUP BY EMP_ID
Facing Issue:
I.e One employee look leave on Friday and Saturday (i.e EMP001 took SL on 2018-11-30 to 2018-12-01) (Friday is month of last date and Saturday is first date of month and I am inserting single record into table. When employee applied leave from application. Here result should be
EMP001 - SL
November - 1 leave
December - 1 leave
How can I write this MySQL query?
Dear Dipti Kindly find below query for required result.
SELECT
*
FROM
(
SELECT
EMP_ID,
START_DATE as date_day,
TYPE_OF_LEAVE,
SUM(
if(
MONTH(START_DATE) <> MONTH(END_DATE),
(
day(
last_day(START_DATE)
)+ 1 - day(START_DATE)
),
days
)
) as DAYS
FROM
APPLY_LEAVE
GROUP BY
MONTH(START_DATE),
MONTH(END_DATE),
EMP_ID
UNION ALL
SELECT
EMP_ID,
END_DATE as date_day,
TYPE_OF_LEAVE,
SUM(
if(
MONTH(START_DATE) <> MONTH(END_DATE),
DAY(END_DATE),
0
)
) as DAYS
FROM
APPLY_LEAVE
GROUP BY
MONTH(START_DATE),
MONTH(END_DATE),
EMP_ID
) as a
WHERE
a.DAYS > 0;
I have a table like this. Now I want to show the total of same dates of different status in single row.
What should be the query?
Expected Result
Created | Total1 | Total2 | Total3
2017-02-28 | 1 | 1 | 2
you could use a sum for case when for each status and group by
select
created
, sum( case when story_status ='Draft' then total else 0 end ) as Draft_count
, sum( case when story_status ='Private' then total else 0 end ) as Private_count
, sum( case when story_status ='Published' then total else 0 end ) as Published_count
from my_table
group by created
This will give you one row per date created, with columns for each story_status:
SELECT
`created`,
SUM(if(`story_status` = 'Draft',`total`,0)) as `Total Draft`,
SUM(if(`story_status` = 'Private',`total`,0)) as `Total Private`,
SUM(if(`story_status` = 'Published',`total`,0)) as `Total Published`
FROM table
GROUP BY `created`
ORDER BY `created`
I have several datetime columns. I need to calculate in SQL Server 2008 for each timestamp how many datetime stamps in the same column are smaller than each of datetime stamps.
For example: for 2016-05-01 14:24:000.00 in column DateTime1 I need to calculate how many datetime values are smaller then it in DateTime1 column.
I also need to know how many datetimestamps are smaller than a datetime stamp for the same record (in the same row) in column DateTime2 and 3.
DateTime1 DateTime2 DateTime3
----------------------------------------------------------------------------
2016-05-01 13:24:000.00 2016-05-01 15:24:000.00 2016-05-01 16:20:000.00
2016-05-01 13:30:000.00 2016-05-01 14:21:000.00 2016-05-01 15:10:000.00
2016-05-01 14:24:000.00 2016-05-01 17:21:000.00 2016-05-01 18:10:000.00
If I understand correctly, you can use rank():
select t.*,
rank() over (order by datetime1) as dt1_rank,
rank() over (order by datetime2) as dt2_rank,
rank() over (order by datetime3) as dt3_rank
from t ;
Depending on how you want to treat tied values, you might actually want dense_rank(). Also, you might want to subtract 1 from the ranking value.
Assume I have a Table name [TestTB] has 3 columns DateTime1,DateTime2,DateTime3 .
I said CountSmallerDateTime1 as "how many datetime values are smaller then it in DateTime1 column"
I said CountSmallerDateTime2 as "how many datetimestamps are smaller than a datetime stamp for the same record (in the same row) in column DateTime2" , Similarity , CountSmallerDateTime3 for DateTime3 .
Then I have a query for your request :
SELECT [DateTime1]
,[DateTime2]
,[DateTime3]
,(SELECT COUNT(1)
FROM [TestTB] Sub
WHERE TB.[DateTime1] >Sub.[DateTime1]) AS CountSmallerDateTime1
,(
CASE WHEN TB.[DateTime2] > TB.[DateTime1] AND TB.[DateTime2] > TB.[DateTime3] THEN
2
WHEN ( (TB.[DateTime2] <= TB.[DateTime1] AND TB.[DateTime2] > TB.[DateTime3])
OR (TB.[DateTime2] > TB.[DateTime1] AND TB.[DateTime2] <= TB.[DateTime3])) THEN
1
ELSE
0
END
) AS CountSmallerDateTime2,
(
CASE WHEN TB.[DateTime3] > TB.[DateTime1] AND TB.[DateTime3] > TB.[DateTime2] THEN
2
WHEN ( (TB.[DateTime3] <= TB.[DateTime1] AND TB.[DateTime3] > TB.[DateTime2])
OR (TB.[DateTime3] > TB.[DateTime1] AND TB.[DateTime3] <= TB.[DateTime2])) THEN
1
ELSE
0
END
) AS CountSmallerDateTime3 FROM [TestTB] TB
;WITH CTE(DATE1, DATE2, DATE3,RN)
AS
(
SELECT CONVERT(DATETIME , '2016-05-01 13:24:000.00'), CONVERT(DATETIME,'2016-05-01 15:24:000.00'), CONVERT(DATETIME,'2016-05-01 16:20:000.00'),1
UNION ALL
SELECT CONVERT(DATETIME , '2016-05-01 13:30:000.00'), CONVERT(DATETIME,'2016-05-01 14:21:000.00'), CONVERT(DATETIME,'2016-05-01 15:10:000.00'),2
UNION ALL
SELECT CONVERT(DATETIME , '2016-05-01 14:24:000.00'), CONVERT(DATETIME,'2016-05-01 17:21:000.00'), CONVERT(DATETIME,'2016-05-01 18:10:000.00'),3
)
SELECT RANK() OVER (ORDER BY DATE1) -1 AS SAME_COLUMN_DATE1
, RANK() OVER (ORDER BY DATE2) -1 AS SAME_COLUMN_DATE2
, RANK() OVER (ORDER BY DATE3) -1 AS SAME_COLUMN_DATE3
, CASE WHEN RN=1 AND DATE1< DATE2 AND DATE1<DATE3 THEN 0
WHEN RN=1 AND DATE1< DATE2 AND DATE1>DATE3 THEN 1
WHEN RN=1 AND DATE1> DATE2 AND DATE1<DATE3 THEN 1
ELSE 2
SAME_ROW_1
, CASE WHEN RN=2 AND DATE2< DATE1 AND DATE2<DATE3 THEN 0
WHEN RN=2 AND DATE2< DATE1 AND DATE2>DATE3 THEN 1
WHEN RN=2 AND DATE2> DATE1 AND DATE2<DATE3 THEN 1
ELSE 2
END SAME_ROW_2
, CASE WHEN RN=3 AND DATE3< DATE1 AND DATE3<DATE2 THEN 0
WHEN RN=3 AND DATE3< DATE1 AND DATE3>DATE2 THEN 1
WHEN RN=3 AND DATE3> DATE1 AND DATE3<DATE2 THEN 1
ELSE 2
END SAME_ROW_3
FROM CTE ORDER BY RN