【问题标题】:Mysql group by two columns with where condition and maximum date of third columnMysql按两列分组,其中条件和第三列的最大日期
【发布时间】:2019-02-18 08:06:33
【问题描述】:

我有一个表,其中包含 user_id、item_id 和 last_date 作为列。最后的列类型在 datetime 中。

我需要通过将列 user_iditem_idtype_id 类似的条件分组来检索 last_date strong>foo 非常重要,我需要在结果中包含所有列,因为在 mytable 中有更多列。

这是 mytable 结构:

user_id  item_id      last_date         type_id
129678      2     2019-02-17 11:00:09     foo
129678      1     2019-02-17 11:00:15     foo
129678      2     2019-02-17 11:00:10     bar
129678      2     2019-02-17 11:00:10     bar
129678      2     2019-02-17 11:00:11     foo
129678      2     2019-02-17 11:00:15     foo
129678      1     2019-02-17 11:00:09     foo
129678      2     2019-02-17 11:00:14     bar
129678      2     2019-02-17 11:00:08     bar
129678      2     2019-02-17 11:00:11     foo
129678      2     2019-02-17 11:00:14     bar
129678      2     2019-02-17 11:00:10     foo
12a0d8      3     2019-02-17 11:00:08     foo
12a0d8      2     2019-02-17 11:00:12     foo
12a0d8      3     2019-02-17 11:00:08     bar
12a0d8      3     2019-02-17 11:00:12     bar
12a0d8      1     2019-02-17 11:00:10     foo
12a0d8      1     2019-02-17 11:00:11     bar
12a0d8      3     2019-02-17 11:00:14     foo
12a0d8      3     2019-02-17 11:00:12     foo
18ae98      2     2019-02-17 11:00:12     foo
18ae98      3     2019-02-17 11:00:07     bar
18ae98      1     2019-02-17 11:00:13     bar
18ae98      1     2019-02-17 11:00:14     foo
18ae98      2     2019-02-17 11:00:09     foo
18ae98      2     2019-02-17 11:00:13     foo
18ae98      3     2019-02-17 11:00:08     foo
18ae98      1     2019-02-17 11:00:12     foo
18ae98      3     2019-02-17 11:00:10     foo
18ae98      1     2019-02-17 11:00:12     foo

这是我为此尝试的查询:

SELECT * FROM mytable
  WHERE last_date IN (
    SELECT MAX(last_date)
    FROM mytable
    WHERE type_id LIKE 'foo'
    GROUP BY user_id, item_id
  )

想要的结果:

user_id  item_id      last_date         type_id
129678      1     2019-02-17 11:00:15     foo
129678      2     2019-02-17 11:00:15     foo
12a0d8      1     2019-02-17 11:00:10     foo
12a0d8      2     2019-02-17 11:00:12     foo
12a0d8      3     2019-02-17 11:00:14     foo
18ae98      1     2019-02-17 11:00:14     foo
18ae98      2     2019-02-17 11:00:13     foo
18ae98      3     2019-02-17 11:00:10     foo

但是结果很奇怪!!例如,为 user_id 返回多个具有相同值的 item_id...

编辑:

如果我使用这个可以很好地工作的查询,但我必须指定一个间隔日期。

SELECT * FROM mytable
WHERE type_id LIKE 'foo'
AND last_date > date_sub(curdate(), interval 2 day)
GROUP BY user_id, item_id

【问题讨论】:

  • 您使用的是哪个 MySQL 版本?
  • 指定预期结果,表格数据如上。
  • @jarlh 我正在使用两个版本:v5.1.47(开发),v5.7.19(产品)。为了得到想要的结果,我更新了我的问题。
  • 我已经用临时解决方案编辑了我的问题。

标签: mysql sql group-by max aggregate-functions


【解决方案1】:

下面是一种方法-

    SELECT 
from       MyTable t1 
INNER JOIN 
           ( 
                    SELECT   user_id, 
                             item_id, 
                             max(last_date) AS lastdate 
                    FROM     MyTable 
                    WHERE    type_id='foo' 
                    GROUP BY user_id, 
                             item_id) t2 
ON         t1.user_id=t2.user_id 
AND        t1.item_id=t2.item_id 
AND        t1.last_date=t2.lastdate

【讨论】:

  • 好吧,如果我使用你的查询来很好地工作 (sqlfiddle.com/#!9/f7c5c2/1) 但在我的数据库中使用 phpMyAdmin 仍然有两倍/三倍的 item_id 值:\跨度>
  • 您能否对获得意外输出的数据进行抽样。仅当您有更多特定条目时,查询才会返回重复项 - user_id, item_id, last_date
【解决方案2】:

使用相关子查询

   SELECT t1.* FROM mytable t1
   WHERE last_date = (
    SELECT MAX(last_date)
    FROM mytable t2
    WHERE t1.user_id=t2.user_id and t1.itemid=t2.itemid    
    and type_id LIKE 'foo'

  )

【讨论】:

  • 现在修复那个双重的WHERE
  • 好吧,如果我使用你的查询来很好地工作 (sqlfiddle.com/#!9/f7c5c2/3) 但在我的数据库中使用 phpMyAdmin 仍然有两倍/三倍的 item_id 值:\ 我必须添加第二个条件“t2.type_id LIKE 'foo'”
  • @ZaynulAbadinTuhin :不,抱歉,我已经用临时解决方案编辑了我的问题。
  • 我认为您在 fiddle 和服务器中的数据不一样,否则无法在 fiddle 但不能在您的服务器中使用它
  • 问题是我不能和你分享数据,因为它是私人的:\抱歉
【解决方案3】:

您可以简单地对您关注的 2 列进行分组,然后获取 max(last_date)。您之前使用的子查询不会限制 max(last_date),因为多个 user_id 和 item_id 组合可以应用于同一日期。

以下是您的示例数据,无需编写额外的嵌套查询即可产生预期结果。

declare @t table (
user_id nvarchar(15),
item_id int,
last_date datetime2,
type_id nvarchar(3)
);

insert into  @t (user_id, item_id, last_date, type_id)
values
('129678',      2,     '2019-02-17 11:00:09',     'foo'),
('129678',      1,     '2019-02-17 11:00:15',     'foo'),
('129678',      2,     '2019-02-17 11:00:10',     'bar'),
('129678',      2,     '2019-02-17 11:00:10',     'bar'),
('129678',      2,     '2019-02-17 11:00:11',     'foo'),
('129678',      2,     '2019-02-17 11:00:15',     'foo'),
('129678',      1,     '2019-02-17 11:00:09',     'foo'),
('129678',      2,     '2019-02-17 11:00:14',     'bar'),
('129678',      2,     '2019-02-17 11:00:08',     'bar'),
('129678',      2,     '2019-02-17 11:00:11',     'foo'),
('129678',      2,     '2019-02-17 11:00:14',     'bar'),
('129678',      2,     '2019-02-17 11:00:10',     'foo'),
('12a0d8',      3,     '2019-02-17 11:00:08',     'foo'),
('12a0d8',      2,     '2019-02-17 11:00:12',     'foo'),
('12a0d8',      3,     '2019-02-17 11:00:08',     'bar'),
('12a0d8',      3,     '2019-02-17 11:00:12',     'bar'),
('12a0d8',      1,     '2019-02-17 11:00:10',     'foo'),
('12a0d8',      1,     '2019-02-17 11:00:11',     'bar'),
('12a0d8',      3,     '2019-02-17 11:00:14',     'foo'),
('12a0d8',      3,     '2019-02-17 11:00:12',     'foo'),
('18ae98',      2,     '2019-02-17 11:00:12',     'foo'),
('18ae98',      3,     '2019-02-17 11:00:07',     'bar'),
('18ae98',      1,     '2019-02-17 11:00:13',     'bar'),
('18ae98',      1,     '2019-02-17 11:00:14',     'foo'),
('18ae98',      2,     '2019-02-17 11:00:09',     'foo'),
('18ae98',      2,     '2019-02-17 11:00:13',     'foo'),
('18ae98',      3,     '2019-02-17 11:00:08',     'foo'),
('18ae98',      1,     '2019-02-17 11:00:12',     'foo'),
('18ae98',      3,     '2019-02-17 11:00:10',     'foo'),
('18ae98',      1,     '2019-02-17 11:00:12',     'foo');

select * from (
select USER_ID, item_id, MAX(last_date) as last_date, type_id 
from @t where type_id = 'foo' group by user_id, item_id, type_id
) x
order by user_id, item_id;

【讨论】:

  • 感谢您的回复,但“分组依据”不在正确的位置(语法)
  • @Peacefull 感谢您指出这一点(因为我没有直接从我的查询窗口粘贴)。我已经移动了 where 子句。查询在运行时确实提供了预期的结果(显然 where 子句在正确的位置)。
  • 没问题,您的查询现在更好了,但是在我的第一个请求中,我需要返回所有列并带有 SELECT * 如果我使用 SELECT 和一些效果很好的列。这是我的问题...
  • 我添加了一个 select * 作为外部查询。我不确定为什么 select * 比单独选择列更可取。然而,发布的查询给出了在建议条件下使用的预期结果。
  • 我尝试了您的最后一次更改,但它窃取了仅返回选定列而不是从我的数据库中返回的所有其他列。
猜你喜欢
  • 2021-12-04
  • 1970-01-01
  • 1970-01-01
  • 2022-11-12
  • 1970-01-01
  • 2017-10-19
  • 1970-01-01
  • 1970-01-01
  • 2019-01-13
相关资源
最近更新 更多