6

我有两个称之为“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
4

4 回答 4

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

于 2014-03-07T10:23:18.473 回答
3

首先,您应该为您的列使用正确的数据类型,例如日期应该有一列数据类型与您的示例数据集中的时间列相同,您将日期格式化为'%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)

小提琴演示

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

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)

小提琴演示

您的问题似乎是greatest-n-per-group问题,因此您可以首先从表tipo_hh_historial最大值中获取最大值,fecha_cambio并且hora_cambio需要使用多个条件进行自我连接以获得最大值,例如

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)

更新了小提琴演示

于 2014-03-06T16:32:33.903 回答
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
于 2013-06-28T06:43:43.763 回答
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);
于 2013-06-28T06:34:30.330 回答