为每个 ID 选择 MAX DATE

Posted

技术标签:

【中文标题】为每个 ID 选择 MAX DATE【英文标题】:SELECT MAX DATE for each ID 【发布时间】:2013-06-25 20:43:53 【问题描述】:

我有两个叫“tipo_hh”和“tipo_hh_historial”。

我需要在两个表之间进行连接,其中两个表中的“id”相同。 但我需要为“tipo_hh”表中的每个“id”选择“tipo_hh_historial”表中的“valor”,条件是“fecha_cambio”和“hora_cambio”最大值的记录。

“id”是表“tipo_hh”中的主键和自增

类似的东西。

这是表“tipo_hh”

id  nombre
1   Reefer
2   Lavados
3   Dry
4   Despacho

这是表格“tipo_hh_historial”

id  valor   fecha_cambio    hora_cambio
1   1.50    27/06/2013  19:15:05
1   5.50    27/06/2013  19:19:32
1   5.50    27/06/2013  19:20:06
1   2.50    27/06/2013  21:03:30
2   4.66    27/06/2013  19:15:17
2   3.00    27/06/2013  19:20:22
3   5.00    27/06/2013  19:20:32
4   1.50    27/06/2013  19:20:50

我需要这个:

id  nombre     valor
1   Reefer     2.50
2   Lavados    3.00
3   Dry        5.00
4   Despacho   1.50

【问题讨论】:

请查看答案并接受... 【参考方案1】:

首先,您应该为您的列使用正确的数据类型,例如日期应该有一列类型数据与您的示例数据集中的时间列相同,您的日期格式为'%d/%m/%Y' id 这可以更改为标准格式'%Y-%m-%d' 这很好,所以下面的查询适用于列的正确类型

SELECT t.* ,new_tipo_hh_historial.`valor`
FROM tipo_hh_new t
JOIN (
SELECT  th.*
FROM tipo_hh_historial_new th
JOIN (
SELECT id,valor,
 MAX(fecha_cambio ) fecha_cambio
,MAX(hora_cambio) hora_cambio
FROM `tipo_hh_historial_new` 
GROUP BY id
) thh 
ON (
th.`id` =thh.`id` 
AND th.fecha_cambio=thh.`fecha_cambio` 
AND th.hora_cambio = thh.`hora_cambio`
)
) new_tipo_hh_historial 
USING (id)

Fiddle Demo

如果您将日期和时间存储为字符串,那么您需要将它们格式化为真实类型,您可以在下面的查询中使用但不推荐

SELECT t.* ,new_tipo_hh_historial.`valor`
FROM tipo_hh t
JOIN (
SELECT  th.*
FROM tipo_hh_historial th
JOIN (
SELECT id,valor,
 MAX(STR_TO_DATE(fecha_cambio , '%d/%m/%Y')) fecha_cambio
,MAX(TIME_FORMAT(hora_cambio,'%H:%i:%s')) hora_cambio
FROM `tipo_hh_historial` 
GROUP BY id
) thh 
ON (
th.`id` =thh.`id` 
AND STR_TO_DATE(th.fecha_cambio , '%d/%m/%Y')=thh.`fecha_cambio` 
AND TIME_FORMAT(th.hora_cambio,'%H:%i:%s') = thh.`hora_cambio`
)
) new_tipo_hh_historial 
USING (id)

Fiddle Demo

您的问题看起来像 greatest-n-per-group 问题,因此您可以首先从表中的最大值 tipo_hh_historial 中获取最大值 fecha_cambiohora_cambio 并且需要在多个条件下自行加入获得像 ie 一样的最大值

ON (
th.`id` =thh.`id` 
AND th.fecha_cambio=thh.`fecha_cambio` 
AND th.hora_cambio = thh.`hora_cambio`
)

然后加入您的第一个表以获得预期结果

编辑:@Kickstart 发现的问题他已经回答了,所以我将提供另一种方法来克服。应该有一个字段来存储日期和时间的记录,如 fecha_cambio DATETIME所以不会错过 id 并获得正确的日期和时间最大值。请参阅下面的更新查询

SELECT t.* ,new_tipo_hh_historial.`valor`
FROM tipo_hh_new t
JOIN (
SELECT  th.*
FROM tipo_hh_historial_alter th
JOIN (
SELECT id,valor,
 MAX(fecha_cambio ) fecha_cambio
FROM `tipo_hh_historial_alter` 
GROUP BY id
) thh 
ON (
th.`id` =thh.`id` 
AND th.fecha_cambio=thh.`fecha_cambio` 
)
) new_tipo_hh_historial 
USING (id)

Updated fiddle demo

【讨论】:

感谢您的回复...我已经解决了我的问题...我用这篇文章解决了我的问题...jan.kneschke.de/projects/mysql/groupwise-max。我忘了注意这个问题中的日期字段......但是我在我的表中使用了日期数据类型......你为这两种情况都提供了解决方案。非常感谢您的努力...我将为您的回应和努力付出 50 分。再次感谢... 怕这个sql有bug。如果对于一个 id,最大 hora_cambio 不在最大 fecha_cambio 上,那么它会错过该 id 的值 @Kickstart 你发布了答案,而我正在使用相同的逻辑来克服你的观点 没问题。完全同意您的观点,单个日期时间字段会更好。 @downvoters 愿意解释您在答案中发现的问题【参考方案2】:

使用子查询来获取每个id的历史记录的最大日期/时间,并使用它来获取其余的最新历史记录:-

SELECT tipo_hh.id, tipo_hh.nombre, tipo_hh_historial.valor
FROM tipo_hh
INNER JOIN 
(
    SELECT id, MAX(STR_TO_DATE(CONCAT(fecha_cambio, hora_cambio), '%d/%m/%Y%k:%i:%s')) AS MaxDateTime
    FROM tipo_hh_historial
    GROUP BY id
) Sub1
ON tipo_hh.id = Sub1.id
INNER JOIN tipo_hh_historial
ON tipo_hh_historial.id = Sub1.id
AND STR_TO_DATE(CONCAT(fecha_cambio, hora_cambio), '%d/%m/%Y%k:%i:%s') = Sub1.MaxDateTime

SQL 小提琴:-

http://www.sqlfiddle.com/#!2/68baa/2

【讨论】:

【参考方案3】:
SELECT tipo_hh.id, tipo_hh.nombre, tipo_hh_historial.valor
   FROM tipo_hh INNER JOIN tipo_hh_historial 
   ON tipo.id = tipo_hh_historial.id AS 
   group by tipo_hh_historial.id 
   Having max(tipo_hh_historial.hora_cambio);

【讨论】:

谢谢!......但这不是我需要的......因为我需要在每个“id”的最大“hora_cambio”和“fecha_cambio”的同一行中选择“valor”的值"【参考方案4】:

试试这个:

SELECT A.id, B.nombre, A.valor, MAX(A.hora_cambio) AS hora_cambio_time
FROM tipo_hh_historial AS A
INNER JOIN tipo_hh AS B
ON(A.id = B.id)
GROUP BY A.id

【讨论】:

谢谢!......但这不是我需要的......因为我需要在每个“id”的最大“hora_cambio”和“fecha_cambio”的同一行中选择“valor”的值"

以上是关于为每个 ID 选择 MAX DATE的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 case 语句中的函数返回值以选择每个函数的 MAX?

如何在 Oracle SQL 中不使用 distinct 选择从多个 max(case when) 派生的唯一行

如何在 CI Active Record 中按 MAX 日期选择

如何按 MAX(日期)选择?

GROUP BY ID 并选择 MAX

从 oracle 中为每个组选择最新行