MySQL子查询 - 获取最新的带时间戳的记录和提取字段

时间:2016-12-01 16:09:08

标签: mysql subquery greatest-n-per-group

我有一个获取表记录的查询,并计算该表的相关记录数。

我想要做的是获取相关表格最新记录的text字段并将其包含在查询中

SELECT DISTINCT
    inst.id, inst.name, inst.state, inst.farm_status,
    (SELECT COUNT(inst_note.id) 
        FROM project_institution_note AS inst_note
        WHERE inst_note.institution_id = inst.id) AS inst_note_count,
    (SELECT COUNT(c.id) FROM project_catalog AS c
        WHERE c.institution_id = inst.id 
        AND c.status = 0 
        AND c.catalog_type BETWEEN 0 AND 1) AS ug_count,
    (SELECT COUNT(c.id) FROM project_catalog AS c
        WHERE c.institution_id = inst.id 
        AND c.status = 0 
        AND c.catalog_type BETWEEN 1 AND 2) AS grad_count,
    (SELECT COUNT(c.id) FROM project_catalog AS c
        WHERE c.institution_id = inst.id 
        AND c.status = 0 
        AND c.catalog_type >= 3) AS alt_count,
    (SELECT COUNT(c.id) FROM project_catalog_note AS cn
        INNER JOIN farmtool_catalog AS c
        ON c.id = cn.catalog_id
        WHERE c.institution_id = inst.id) AS catalog_note_count,
    (SELECT inst_note.text FROM project_institution_note AS inst_note  -- Issue portion of query
        LEFT JOIN project_institution AS inst
        ON inst_note.institution_id = inst.id
        WHERE inst_note.institution_id = inst.id
        ORDER BY inst_note.date DESC
        LIMIT 1) AS latest_note
FROM project_institution AS inst
LEFT JOIN project_institution_note AS inst_note
ON inst.id = inst_note.institution_id
LEFT JOIN project_catalog AS c
ON inst.id = c.institution_id
WHERE LOWER(inst.state) = "me";

这里发生的是它获取project_institution_note中的最后一条记录并提供text作为查询中的值。使用此子查询,我该怎么做

  1. project_institution_note的选择限制为相关的project_institution.id AND
  2. 选择最近的带时间戳的记录。
  3. 我已经完成了#2,但我需要帮助限制#1中的结果集。有什么想法吗?

2 个答案:

答案 0 :(得分:2)

最新记录,嗯?也就是说,来自project_institution_note的记录具有最新date值?

如果project_institution_noteid列自动递增,并且您只是INSERT并且永远不会更新该表,这很容易。这是一个子查询,可获取每个text的最新institution_id值。

                  SELECT a.institution_id, a.text
                    FROM project_institution_note a
                    JOIN (   SELECT MAX(id) id
                               FROM project_institution_note
                              GROUP BY institution_id
                         ) b ON a.id = b.id

这基本上使用每个机构的最大id值列表来查找最新的text

如果您必须使用date列,则稍微更难,但遵循相同的模式。 (如果两个date值相同,则会得到两个结果。)

                  SELECT a.institution_id, a.text
                    FROM project_institution_note a
                    JOIN (   SELECT institution_id,
                                    MAX(date) date
                               FROM project_institution_note
                              GROUP BY institution_id
                         ) b  ON a.date = b.date
                             AND a.institution_id = b.institution_id                    

然后,您可以将其用作独立(不相关)子查询,并将其与其他内容联系起来。这是一个例子

  SELECT inst.id, inst.name, inst.state, inst.farm_status,
         note.text
    FROM project_institution inst
    LEFT JOIN (
                /* the subquery from above */
         ) note ON inst.id = note.institution_id

使用LEFT JOIN代替JOIN可以阻止查询在没有注释的情况下抑制结果。

您的查询中有许多依赖子查询。 MySQL在依赖子查询中是可怕的。您可能希望将它们重构为独立的子查询,而是将它们连接起来。

答案 1 :(得分:0)

我最终找到了解决方案。

作为SELECT中字段声明的一部分,我定义inst.id来自project_institution。在SELECT子查询的内部,我还说我希望来自`project_institution的inst.id,它重新声明了该别名。

更改子查询中的inst

SELECT inst_note.text FROM project_institution_note AS inst_note
    LEFT JOIN project_institution AS `inst`
    ON inst_note.institution_id = `inst.id`
    WHERE inst_note.institution_id = `inst.id`

institutioninstitution.id分别做了这个伎俩。