如何从下一条记录中获取列值

时间:2018-04-19 11:35:30

标签: mysql sql

我有以下结果集:

POST                   |    DATE
--------------------------------------
Senior Software Engg.  |    2018-04-18
Software Engg.         |    2017-04-18
Assoc. Software Engg.  |    2016-04-18

SQL查询:

SELECT DISTINCT designation_id as id, d.title as POST, DATE(dt_datetime) as DATE
    FROM users_history_check u
    INNER JOIN
    designations d 
    ON d.id = u.designation_id
    WHERE u.id = $userID
    ORDER BY DATE DESC

我想获取下一条记录并在几个月内执行日期差异计算,并显示记录。

预期产出:

POST                   |    Start DATE  |  End DATE   |  MONTHS
---------------------------------------------------------------
Senior Software Engg.  |    2018-04-18  |   -         |
Software Engg.         |    2017-04-18  |  2018-04-18 |  12
Assoc. Software Engg.  |    2016-04-18  |  2017-04-18 |  12

类似的东西:

SELECT DISTINCT designation_id as id, d.title as POST, DATE(dt_datetime) as Start DATE, NEXT_RECORD(DATE(dt_datetime)) as End DATE, DATEDIFF(Start DATE, End DATE) as MONTHS....

非常感谢任何帮助。感谢。

5 个答案:

答案 0 :(得分:4)

SELECT `POST`, 
        `DATE`,
        IFNULL(END_DATE,'') AS END_DATE,
        IFNULL(MONTH,'') AS MONTH
FROM
(SELECT `POST`, 
        `DATE`,
        @prev AS END_DATE,
        TIMESTAMPDIFF(month,DATE,@prev) AS MONTH,
        @prev := T.DATE AS VarDate
FROM Table1 T,
(SELECT @prev:=null)R
) T1

<强>输出

POST                    DATE        END_DATE    MONTH
Senior Software Engg.   2018-04-18      
Software Engg.          2017-04-18  2018-04-18  12
Assoc. Software Engg.   2016-04-18  2017-04-18  12

演示链接

  

http://sqlfiddle.com/#!9/33260/15

<强>说明

在Sub查询中,我将Date值保存在@prev变量中,并在每行中使用该变量计算END_DATE,然后从列{{1}中分配当前日期值}}。 然后使用子查询以适当的方式显示数据。

答案 1 :(得分:2)

您可以使用变量获取上一个日期:

SELECT id, post, date,
       (CASE WHEN (@tmp_prevd := @prevd) = NULL THEN NULL  -- never happens
             WHEN (@prevd := date) = NULL THEN NULL  -- never happens
             ELSE @tmp_prevd
        END) as prev_date
FROM (SELECT DISTINCT designation_id as id, d.title as POST, DATE(dt_datetime) as DATE
      FROM users_history_check u INNER JOIN
           designations d 
           ON d.id = u.designation_id
      WHERE u.id = $userID
      ORDER BY DATE DESC
     ) ud CROSS JOIN
     (SELECT @prevd := NULL) params;

这很棘手,因为对变量的所有引用都需要在同一个表达式中。这就是为什么它以一种相当晦涩的方式使用CASE

在MySQL 8.0和基本上所有其他数据库中,您可以使用LEAD()代替。

答案 2 :(得分:2)

试试这个......

 SELECT T1.POST,T1.DATE  ,T2.DATE,DATEDIFF(MONTH,T1.DATE,T2.DATE)
 FROM(

   SELECT ROW_NUMBER()OVER(ORDER BY DATE DESC) AS SlNo,*
   FROM Mytable)T1
   LEFT JOIN (SELECT ROW_NUMBER()OVER(ORDER BY DATE DESC)+1 AS SlNo,*
   FROM Mytable)T2
   ON(T1.SlNo = T2.SlNo  )

答案 3 :(得分:1)

我建议像这样使用自联接

select d1.post, 
       d1.d `start DATE`, 
       min(d2.d) `end DATE`, 
       timestampdiff(month, d1.d, min(d2.d)) `MONTHS`
from data d1
left join data d2 on d1.d < d2.d
group by d1.post, d1.d

dbfiddle demo

数据表是SQL的结果。它可以使用WITH添加,也可以使用子查询。

答案 4 :(得分:1)

SELECT * ,Datediff(Month,[Date],endate) 
FROM
(
SELECT *,Lead( [Date], 1, Null) OVER (
     ORDER BY [Date]) AS Endate --INTO SourceTable 
FROM
(                  
SELECT 'Senior Software Engg.' POST    ,   '2018-04-18' DATE UNION ALL
SELECT 'Software Engg.'        POST    ,   '2017-04-18' DATE UNION ALL
SELECT 'Assoc. Software Engg.'  POST   ,    '2016-04-18' DATE 
)A
)B
ORDER BY [Date] desc