Search code examples
mysqlsqlcasecase-when

set a variable in mysql based on case when-then


I have a Projects table, containing three columns: Task_ID, Start_Date and End_Date. I'm trying two increment a variable named count whenever the difference between previous row's End_Date and current row's Start_Date is not equals to zero but it's getting incremented for every row. So, how can I change the value of a variable in mysql based on CASE when-then statements?


SQL QUERY -

SET @count := 0;
SELECT
*,
LAG(end_date) OVER(ORDER BY start_date) as prev,
DATEDIFF(LAG(end_date) OVER(ORDER BY start_date), start_date) as diff,
(CASE
    WHEN DATEDIFF(LAG(end_date) OVER(ORDER BY start_date), start_date) is NULL
    THEN @count
    WHEN DATEDIFF(LAG(end_date) OVER(ORDER BY start_date), start_date) = 0
    THEN @count
    ELSE @count := @count + 1
END) as cnt
FROM projects
;

OUTPUT -

task_id start_date end_date prev         diff cnt
1      2015-10-01 2015-10-02 NULL        NULL 1
24     2015-10-02 2015-10-03 2015-10-02   0   2
2      2015-10-03 2015-10-04 2015-10-03   0   3
23     2015-10-04 2015-10-05 2015-10-04   0   4
3      2015-10-11 2015-10-12 2015-10-05  -6   5
22     2015-10-12 2015-10-13 2015-10-12   0   6
4      2015-10-15 2015-10-16 2015-10-13  -2   7
21     2015-10-17 2015-10-18 2015-10-16  -1   8
5      2015-10-19 2015-10-20 2015-10-18  -1   9

EXPECTED OUTPUT -

task_id start_date end_date prev         diff cnt
1      2015-10-01 2015-10-02 NULL        NULL 0
24     2015-10-02 2015-10-03 2015-10-02   0   0
2      2015-10-03 2015-10-04 2015-10-03   0   0
23     2015-10-04 2015-10-05 2015-10-04   0   0
3      2015-10-11 2015-10-12 2015-10-05  -6   1
22     2015-10-12 2015-10-13 2015-10-12   0   1
4      2015-10-15 2015-10-16 2015-10-13  -2   2
21     2015-10-17 2015-10-18 2015-10-16  -1   3
5      2015-10-19 2015-10-20 2015-10-18  -1   4

Solution

  • You don't. Use use window functions:

    SELECT p.*,
           SUM(diff < 0) OVER (ORDER BY start_date)
    FROM (SELECT p.*,
                 LAG(end_date) OVER(ORDER BY start_date) as prev,
                 DATEDIFF(LAG(end_date) OVER (ORDER BY start_date), start_date) as diff
          FROM projects p
         ) p;
    

    The SUM(diff < 0) is shorthand for SUM(CASE WHEN diff < 0 THEN 1 ELSE 0 END). MySQL treats booleans as integers in an arithmetic context.