【问题标题】:Mysql: Select most recent entry by user and case numberMysql:按用户和案例编号选择最近的条目
【发布时间】:2012-01-07 23:00:16
【问题描述】:

我有一张表,其数据如下所示:

INSERT INTO `cm_case_notes` (`id`, `case_id`, `date`, `time`, `description`, `username`,       `supervisor`, `datestamp`) VALUES
(45977, '1175', '2010-11-19 16:27:15', 600, 'Motion hearing...Denied.', 'bjones', 'jharvey,', '2010-11-19 21:27:15'),
(46860, '1175', '2010-12-11 16:11:19', 300, 'Semester Break Report', 'bjones', 'jharvey,', '2010-12-11 21:11:19'),
(48034, '1175', '2011-05-04 17:30:03', 300, 'test', 'bjones', 'jharvey,', '2011-05-04 22:30:03'),
(14201, '1175', '2009-02-06 00:00:00', 3600, 'In court to talk to prosecutor, re: the file', 'csmith', 'sandrews', '2009-02-07 14:33:34'),
(14484, '1175', '2009-02-13 00:00:00', 6300, 'Read transcript, note taking', 'csmith', 'sandrews', '2009-02-16 17:22:36');

我正在尝试为每个用户选择每个案例的最新案例注释(date)。我想出的最好的是:

SELECT * , MAX(  `date` ) FROM cm_case_notes WHERE case_id =  '1175' GROUP BY username

然而,这并没有给出最近的条目,而是每个用户的第一个条目。我在这里看到了几个类似的帖子,但我似乎无法理解它们。有人会同情sql缺陷并提供帮助吗?

【问题讨论】:

  • 按用户名分组将为您提供每个用户的最新信息。在这种情况下,每个响应 case_id = 1175 的用户。您显然会有很多案例。您真正想要的是……对于每个案例 ID,您想要最新的案例评论吗?然后也许按日期对它们进行分组?或...在给定日期(或范围)内有活动的所有案例,与该范围相关的案例的最新案例说明?你的问题不够明确。
  • 试试右边的链接(在相关下)

标签: mysql greatest-n-per-group


【解决方案1】:

如果您只想要每个用户和每个案例的最新案例注释的日期,您可以使用这个:

--- Q ---
SELECT case_id
     , username 
     , MAX(  `date` ) AS recent_date 
FROM cm_case_notes 
GROUP BY case_id
       , username 

如果您想要这些行中的所有列(最新日期),请点击 Quassnoi 链接以获取各种解决方案(或其他提供的链接)。最简单的编写方法是将上述查询变成子查询并将其加入cm_case_notes

SELECT cn.*
FROM 
      cm_case_notes AS cn
  JOIN 
      ( Q ) AS q
    ON  ( q.case_id,  q.username,  q.recent_date ) 
      = ( cn.case_id, cn.username, cn.`date` )

如果您只需要 lastet 案例注释但只针对特定的 case_id,那么您可以在 cnQ 中添加 where 条件(Q 稍作修改):

SELECT cn.*
FROM 
      cm_case_notes AS cn
  JOIN 
      ( SELECT username 
             , MAX(  `date` ) AS recent_date 
        FROM cm_case_notes 
        WHERE case_id = @particular_case_id
        GROUP BY username 
      ) AS q
    ON  ( q.username,  q.recent_date ) 
      = ( cn.username, cn.`date` )
WHERE cn.case_id = @particular_case_id

【讨论】:

  • 谢谢,这很有帮助,但我想按大小写查询(case_id 等于目标案例编号的最新条目的所有列)。我应该把 where 子句放在哪里?
  • 如果您只想要特定 case_id 的最新案例注释,那么您可以在 cnQ 中添加 teh where。
  • 运行此程序时出现语法错误。只是要明确一点:在最后一个示例中,我应该将第一个示例中的 sql 放入 for Q 并将@particular_case_id 替换为案例编号,对吗? SELECT cn.* FROM cm_case_notes AS cn JOIN ( SELECT case_id , username , MAX( date ) AS recent_date FROM cm_case_notes GROUP BY case_id , username WHERE case_id = '1175' GROUP BY username ) AS q ON ( q.username, q.最近日期) = (cn.username, cn.date) WHERE cn.case_id = '1175'
  • @Judson:你快到了。 Q 子查询中只能有一个GROUP BY。删除GROUP BY case_id , username
【解决方案2】:

您没有得到想要从数据库中获取的内容的原因是SELECT *GROUP 一起使用。

事实上,只有聚合函数的结果和/或组字段本身可以被安全地选择。选择其他任何东西都会导致意想不到的结果。 (具体结果取决于顺序、查询优化等)。

您要实现的目标称为获取“分组最大值”。这是 SQL 中的常见问题/常见任务,您可以在此处阅读一篇不错的文章: http://jan.kneschke.de/projects/mysql/groupwise-max/

或在此处的 MySQL 手册中: http://dev.mysql.com/doc/refman/5.1/en/example-maximum-column-group-row.html

或 stackoverflow 用户 Quassnoi 的详细解释: http://explainextended.com/2009/11/24/mysql-selecting-records-holding-group-wise-maximum-on-a-unique-column/

【讨论】:

    【解决方案3】:

    您是否考虑过 DESC 排序并仅限制 1?

    【讨论】:

    • 恐怕不行。我希望返回的每个用户都有一个案例中的最新条目。
    猜你喜欢
    • 1970-01-01
    • 2017-03-19
    • 1970-01-01
    • 2020-04-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-17
    • 2016-05-08
    • 1970-01-01
    相关资源
    最近更新 更多