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

MySQL获取每个项目的最后一条记录,mysql,Mysql,我已经做了两天了,想不出来。希望有人能帮助我 我有几个具有一对多关系的表 这很难解释,因此下面是相关表的示例(文件id来自另一个表,与此问题无关,我们在本例中查找的文件id为1) t1.action\u id与t3.file\u action\u id t2.项目id与t3.文件项目id t1.文件id与t2.文件id 我正在尝试获取特定文件的每个项目的上次状态(本例中为文件id 1) 预期结果: +----------------+-----------------+------------+

我已经做了两天了,想不出来。希望有人能帮助我

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

这很难解释,因此下面是相关表的示例(文件id来自另一个表,与此问题无关,我们在本例中查找的文件id为1)

t1.action\u id
t3.file\u action\u id

t2.项目id
t3.文件项目id

t1.文件id
t2.文件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)
我试着使用
groupby
orderby
,但对我来说没有用

尝试此查询

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

好的,您需要特定文件的每个项的最新状态,因此,我要做的是,使用一个只有最新状态的表进行
内部联接

为此,我将使用具有正确数据的子查询(该子查询将仅获取具有最大状态id值的行,我选中此选项以实现它:)来代替使用
文件项目状态的
左连接

在这个子查询中,您必须将其与main左连接:

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)

INNER 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 ) AS t5
ON (t2.id = t5.file_item_id)

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

GROUP BY file_item_id
我运行它,并抛出完全是你想要的结果,享受

试试这个:

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)

谢谢,效果很好!另一个答案也适用。我没有太多数据来测试效率。我想把效率更高的一个标记为答案,因为它们都能工作。唯一知道这一点的方法是:在插入数百个虚拟数据后在您的机器中运行这两个,并检查什么更快。无论如何,在子查询中,您可以更改我提供的方式(答案中的第一个选项)和我选中的答案中的第二个选项来实现它。这样你以后就可以改进它了。啊!!别忘了包括适当的索引!(使用用于连接的字段构建它们)小心使用IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-IN-。我在一个WHERE-in-SQL中使用它来检索社交网络中朋友的帖子,我不得不改变它,因为当一个人有300多个朋友时,它会疯狂地减慢查询速度
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)

INNER 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 ) AS t5
ON (t2.id = t5.file_item_id)

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

GROUP BY file_item_id
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)