每个ID的SELECT MAX DATE

时间:2013-06-28 06:28:47

标签: mysql join max greatest-n-per-group

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

我需要在两个表之间建立连接,其中“id”在两个表中都是相同的。 但我需要为表格“tipo_hh”中的每个“id”选择表“tipo_hh_historial”上的“valor”,其条件是“fecha_cambio”和“hora_cambio”maxima。

“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

4 个答案:

答案 0 :(得分:4)

使用子查询获取每个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

答案 1 :(得分:2)

首先,你应该为你的列使用正确的数据类型,比如日期应该有一个类型数据列与你的样本数据集中的时间列相同,你的日期格式为'%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_historialfecha_cambio的{​​{1}}最大值表中获取最大值需要自我加入多个条件才能获得最大值,例如

hora_cambio

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

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

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

Updated fiddle demo

答案 2 :(得分:0)

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);

答案 3 :(得分:0)

试试这个:

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