MySQL获得每个项目的最后一条记录

时间:2014-02-20 07:37:23

标签: mysql

我已经待了两天,无法弄明白。希望有人可以帮助我。

我有几个表有一对多的关系。

很难解释,所以这里有相关表格的例子(文件ID来自另一个表,与此问题无关,我们在这个例子中寻找的文件ID是1)

Table 1 - history
+----+---------+---------+-----------+---------------------+
| id | file_id | user_id | action_id | datetime            |
+----+---------+---------+-----------+---------------------+
|  1 |       1 |       1 |         1 | 2014-02-19 19:19:49 |
|  2 |       1 |       1 |         2 | 2014-02-19 19:20:06 |
|  3 |       1 |       1 |         3 | 2014-02-19 19:32:09 |
|  4 |       2 |       2 |         1 | 2014-02-20 11:52:59 |
|  5 |       2 |       2 |         2 | 2014-02-20 11:53:08 |
+----+---------+---------+-----------+---------------------+

Table 2 - file_items
+----+---------+------------+---------------+
| id | file_id | item_id    | remark        |
+----+---------+------------+---------------+
|  1 |       1 |          1 | item1 remark  |
|  2 |       1 |         20 | item2 remarks |
|  3 |       2 |          2 | test          |
+----+---------+------------+---------------+

Table 3 - item_statuses
+----+----------------+--------------+----------------+----------------------+
| id | file_action_id | file_item_id | item_status_id | comment              |
+----+----------------+--------------+----------------+----------------------+
|  1 |              2 |            1 |              1 |                      |
|  2 |              2 |            2 |              1 |                      |
|  3 |              3 |            1 |              2 | status comment       |
|  4 |              3 |            2 |              1 | item2 status comment | 
|  5 |              5 |            3 |              1 |                      |
+----+----------------+--------------+----------------+----------------------+

t1.action_idt3.file_action_id

相关

t2.item_idt3.file_item_id

相关

t1.file_idt2.file_id

相关

我正在尝试获取特定文件的每个项目的最后状态(在这种情况下为文件ID 1)。

期望的结果:

+----------------+-----------------+------------+---------------------+----------------+----------------------+
| file_action_id | file_item_id | remark        | file_item_status_id | item_status_id | COMMENT              |
+----------------+-----------------+------------+---------------------+----------- ----+----------------------+
|              3 |            1 | item1 remark  |                   3 |              2 | status comment       |
|              3 |            2 | item2 remarks |                   4 |              1 | item2 status comment |
+----------------+--------------+---------------+---------------------+----------------+----------------------+

我得到了什么:

+----------------+-----------------+------------+---------------------+----------------+----------------------+
| file_action_id | file_item_id | remark        | file_item_status_id | item_status_id | COMMENT              |
+----------------+-----------------+------------+---------------------+----------  -----+---------------------+
|              3 |            1 | item1 remark  |                   1 |              1 |                      |
|              3 |            1 | item1 remark  |                   3 |              2 | status comment       |
|              3 |            2 | item2 remarks |                   2 |              1 |                      |
|              3 |            2 | item2 remarks |                   4 |              1 | item2 status comment |
+----------------+--------------+---------------+---------------------+----------------+----------------------+

查询:

SELECT
t1.id AS file_action_id,
t2.id AS file_item_id,
t2.remark AS remark,
t5.id AS file_item_status_id,
t5.item_status_id AS item_status_id,
t5.comment AS COMMENT

FROM `file_history` AS t1

LEFT JOIN `file_items` AS t2
ON (t1.file_id = t2.file_id)

LEFT JOIN `file_item_statuses` AS t5
ON (t2.id = t5.file_item_id)

WHERE t1.file_id = 1
AND
t1.id = (SELECT MAX(id) FROM `file_history` WHERE file_id = 1)

我尝试使用GROUP BYORDER BY,但它没有为我做。

SQL FIDDLE HERE

3 个答案:

答案 0 :(得分:1)

好的,所以你想要特定文件的每个项目的最新状态,那么,我会做的是INNER JOIN使用只有最新状态的表。

为了做到这一点,而不是带有LEFT JOIN的{​​{1}},我会file_item_statuses使用带有正确数据的子查询(子查询只会获得状态ID值最大的行,我检查了这个以实现它:SQL Select only rows with Max Value on a Column

LEFT JOIN

这个子查询,你必须将它与主要部分LEFT JOIN:

SELECT fs.id          
     , fs.file_item_id
     , fs.item_status_id
     , fs.comment  
FROM file_item_statuses fs
INNER JOIN (
    SELECT MAX(id) AS id
    FROM file_item_statuses
    GROUP BY file_item_id
    ) maxfs 
ON maxfs.id = fs.id

我运行它并准确地输出您想要的结果,享受!

答案 1 :(得分:1)

试试这个:

SELECT
t1.id AS file_action_id,
t2.id AS file_item_id,
t2.remark AS remark,
t5.id AS file_item_status_id,
t5.item_status_id AS item_status_id,
t5.comment AS COMMENT


FROM `file_history` AS t1

LEFT JOIN `file_items` AS t2
ON (t1.file_id = t2.file_id)

LEFT JOIN `file_item_statuses` AS t5
ON (t2.id = t5.file_item_id)

WHERE t1.file_id = 1
AND
t1.id = (SELECT MAX(id) FROM `file_history` WHERE file_id = 1)
# Add the follow condition to fecth max id in file_item_statuses of each item
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
and t5.id in (SELECT MAX(t3.id) 
            FROM `file_item_statuses` t3, `file_items` t4 
            WHERE t4.id = t3.file_item_id 
            AND t4.file_id = 1 
            GROUP BY t4.id)
#GROUP BY t2.id
#ORDER BY MAX(file_item_status_id)

SQL Fiddle

答案 2 :(得分:0)

尝试此查询

SELECT
t1.id AS file_action_id,
t2.id AS file_item_id,
t2.remark AS remark,
t5.id AS file_item_status_id,
t5.item_status_id AS item_status_id,
t5.comment AS COMMENT


FROM `file_history` AS t1

LEFT JOIN `file_items` AS t2
ON (t1.file_id = t2.file_id)

LEFT JOIN `file_item_statuses` AS t5
ON (t2.id = t5.file_item_id)

WHERE t1.file_id = 1
AND
t1.id = (SELECT MAX(id) FROM `file_history` WHERE file_id = 1)
GROUP BY t1.id,t2.id