从一个表中选择行,使用一对多关系连接其他表中的最近一行

时间:2012-02-02 10:24:09

标签: mysql join one-to-many

我想要做的是从一个表(表A)中选择一组特定行并与另一个表(表B)连接,这样只有一个记录将从表A中出现,与最新记录一起加入来自表B,基于日期时间列。

例如,表A具有这种结构(大大简化):

id | col_1     | col_2          
---+-----------+----------------
1  | something | something else 
2  | val_1     | val_2
3  | stuff     | ting
4  | goats     | sheep

表B看起来像这样:

id | fk_A      | datetime_col        | col_3
---+-----------+---------------------+--------
1  | 1         | 2012-02-01 15:42:14 | Note 1
2  | 1         | 2012-02-02 09:46:54 | Note 2
3  | 1         | 2011-11-14 11:18:32 | Note 3
4  | 2         | 2009-04-30 16:49:01 | Note 4
5  | 4         | 2013-06-21 15:42:14 | Note 5
6  | 4         | 2011-02-01 18:44:24 | Note 6

我想要的是一个如下所示的结果集:

id | col_1     | col_2          | datetime_col        | col_3
---+-----------+----------------+---------------------+--------
1  | something | something else | 2012-02-02 09:46:54 | Note 2
2  | val_1     | val_2          | 2009-04-30 16:49:01 | Note 4
3  | stuff     | ting           | NULL                | NULL
4  | goats     | sheep          | 2013-06-21 15:42:14 | Note 5

因此,您可以看到表B已与B.fk_A = A.id上的表A相关联,但结果中仅包含B中最新的相应记录。

我尝试了SELECT DISTINCTLEFT JOIN和子查询的各种组合,我无法让它工作,我要么得不到结果,要么就是这样:

id | col_1     | col_2          | datetime_col        | col_3
---+-----------+----------------+---------------------+--------
1  | something | something else | 2012-02-01 15:42:14 | Note 1
1  | something | something else | 2012-02-02 09:46:54 | Note 2
1  | something | something else | 2011-11-14 11:18:32 | Note 3
2  | val_1     | val_2          | 2009-04-30 16:49:01 | Note 4
3  | stuff     | ting           | NULL                | NULL
4  | goats     | sheep          | 2013-06-21 15:42:14 | Note 5
4  | goats     | sheep          | 2011-02-01 18:44:24 | Note 6

...重复表A中的记录。

显然我的SQL-fu对这项任务来说还不够好,所以如果你们中的一个善良的人能指出我正确的方向,我将非常感激。我已经做了很多谷歌搜索和搜索SO,我没有发现任何匹配这个特定任务,虽然我确定之前已经问过这个问题 - 我怀疑有一个SQL关键字,我忘了/不知道和如果我搜索到,我会立即找到答案。

我认为this question处理相同的问题,虽然我不是100%肯定,并且接受的答案涉及SELECT TOP,我认为(?)在MySQL中无效。

由于我的实际查询要复杂得多并且加入了几个表格,我将展示它以防万一它如何完成:

SELECT  `l` . * ,  `u`.`name` AS  'owner_name',  `s`.`name` AS  'acquired_by_name',  `d`.`type` AS  `dtype` ,  `p`.`type` AS  `ptype` 
FROM  `leads` l
LEFT JOIN  `web_users` u ON  `u`.`id` =  `l`.`owner` 
LEFT JOIN  `web_users` s ON  `s`.`id` =  `l`.`acquired_by` 
LEFT JOIN  `deal_types` d ON  `d`.`id` =  `l`.`deal_type` 
LEFT JOIN  `property_types` p ON  `p`.`id` =  `l`.`property_type`

此查询有效并返回我想要的数据(有时我也会添加WHERE子句,但这样可以正常工作),但我现在想:

LEFT JOIN `notes` n ON  `n`.`lead_id` =  `l`.`id`

... notes包含“多条记录”,leads包含与之相关的“一条记录”。

还应该注意的是,我可能还希望返回最旧的记录(在不同的查询中),但我想这将是一个简单的情况,在某处反转ASC / DESC,或类似的容易。

1 个答案:

答案 0 :(得分:4)

我认为这会对你有所帮助:

SELECT A.id, A.col_1, A.col_2, A.datetime_col, A.col_3
FROM
    (SELECT B.id, B.col_1, B.col_2, C.datetime_col, C.col_3
    FROM tableA B LEFT OUTER JOIN tableB C ON B.id = C.id
    ORDER BY C.datetime_col desc) as A
GROUP BY A.id