使用相同的ID确定前一记录的时间跨度

问题描述 投票:0回答:2

我有一张表,在不同的日期有多次出现相同的动物ID。

tableA
+-----------+------------+
| animalid  |  calvdate  |
+-----------+------------+
| A         | 2018-08-30 |
| B         | 2018-08-30 |
| A         | 2018-09-10 |
| C         | 2018-08-30 |
| A         | 2019-08-30 |
+-----------+------------+

我想创建一个表来计算自上次记录动物日期以来的天数

expected output
+-----------+------------+--------------+
|  animalid |  calvdate  | NumberOfDays |
+-----------+------------+--------------+
| A         | 2018-08-30 |            0 |
| A         | 2018-09-10 |           11 |
| A         | 2019-08-30 |          355 |
| B         | 2018-08-30 |            0 |
| C         | 2018-08-30 |            0 |
+-----------+------------+--------------+

我试过使用以下查询:

SELECT
  animalid,
  calvdate, TO_DAYS(x.calvdate)-TO_DAYS(calvdate) AS NumberOfDays, 
  (SELECT calvdate FROM tableA as x WHERE animalid = animalid ORDER BY asc)
FROM
  tableA 

如何生成预期的输出?

mysql mysql-5.6
2个回答
2
投票

此查询将为您提供所需的结果。它LEFT JOINs原始表本身,其中第二个表中的calvdate是最小calvdate少于第一个。然后我们使用这两个日期的差异来获得时间长度,使用COALESCE来处理第二个表中没有匹配的行:

SELECT a.animalid, a.calvdate, 
       COALESCE(TIMESTAMPDIFF(DAY, b.calvdate, a.calvdate), 0) AS NumberOfDays
FROM tableA a
LEFT JOIN tableA b ON b.animalid = a.animalid AND
                      b.calvdate = (SELECT MAX(calvdate) 
                                    FROM tableA a2 
                                    WHERE a2.calvdate < a.calvdate 
                                      AND a2.animalid = a.animalid)
ORDER BY a.animalid

输出:

animalid    calvdate    NumberOfDays
A           2018-08-30  0
A           2018-09-10  11
A           2019-08-30  354
B           2018-08-30  0
C           2018-08-30  0

Demo on dbfiddle


1
投票

您可以使用此查询:

SELECT tableA.animalid,tableA.calvdate,TO_DAYS(tableA.calvdate)-TO_DAYS(x.calvdate) AS NumberOfDays 
    FROM tableA 
    inner join (
        SELECT MIN(calvdate), animalid FROM tableA GROUP BY animalid)
    ) x ON tableA.animalid = x.animalid

它用于将子查询中的所有动物的最小日期作为连接,并将其用于减法以查找“天数”字段。

© www.soinside.com 2019 - 2024. All rights reserved.