mysql 同时使用ORDER BY和GROUP BY

r8uurelv  于 2023-01-12  发布在  Mysql
关注(0)|答案(8)|浏览(160)

我的表如下所示(我使用的是MySQL):

m_id | v_id | timestamp
------------------------
6    |   1  | 1333635317
34   |   1  | 1333635323
34   |   1  | 1333635336
6    |   1  | 1333635343
6    |   1  | 1333635349

我的目标是获取每个m_id一次,并按最高的时间戳排序。
结果应为:

m_id | v_id | timestamp
------------------------
6    |   1  | 1333635349
34   |   1  | 1333635336

我写了这个查询:

SELECT * FROM table GROUP BY m_id ORDER BY timestamp DESC

但是,结果是:

m_id | v_id | timestamp
------------------------
34   |   1  | 1333635323
6    |   1  | 1333635317

我认为这是因为它首先执行GROUP_BY,然后对结果进行排序。
有什么主意吗?谢谢。

mo49yndu

mo49yndu1#

正确使用group by的一种方法是:

select l.* 
from table l
inner join (
  select 
    m_id, max(timestamp) as latest 
  from table 
  group by m_id
) r
  on l.timestamp = r.latest and l.m_id = r.m_id
order by timestamp desc

工作原理:

  • 选择子查询中每个不同m_id的最新时间戳
  • 只从table中选择与子查询中的行匹配的行(这个操作--执行了连接,但没有从第二个表中选择列,它只是用作过滤器--如果您好奇的话,它被称为“半连接”)
  • 对行进行排序
jum4pzuy

jum4pzuy2#

如果您真的不关心将获得哪个时间戳,并且对于给定的m_i,您的v_id始终相同,则可以执行以下操作:

select m_id, v_id, max(timestamp) from table
group by m_id, v_id
order by max(timestamp) desc

现在,如果v_id对于给定的m_id发生了变化,则应该执行以下操作

select t1.* from table t1
left join table t2 on t1.m_id = t2.m_id and t1.timestamp < t2.timestamp
where t2.timestamp is null
order by t1.timestamp desc
xnifntxz

xnifntxz3#

下面是最简单的解决方案

select m_id,v_id,max(timestamp) from table group by m_id;

按m_id分组,但获取每个m_id的最大时间戳。

bcs8qyzn

bcs8qyzn4#

你可以试试这个

SELECT tbl.* FROM (SELECT * FROM table ORDER BY timestamp DESC) as tbl
 GROUP BY tbl.m_id
1l5u6lss

1l5u6lss5#

SQL语言〉

SELECT interview.qtrcode QTR, interview.companyname "Company Name", interview.division Division 
FROM interview 
JOIN jobsdev.employer 
    ON (interview.companyname = employer.companyname AND employer.zipcode like '100%')
GROUP BY interview.qtrcode, interview.companyname, interview.division
ORDER BY interview.qtrcode;
ktecyv1j

ktecyv1j6#

刚开始我试着理解问题和答案时感到困惑,我花了一些时间阅读,我想做一个总结。

  1. OP的例子有点误导,一开始我不明白为什么accepted答案就是accepted答案......我以为OP的要求可以简单的用
select m_id, v_id, max(timestamp) as max_time from table
group by m_id, v_id
order by max_time desc

然后我又看了一下这个被接受的答案,我发现实际上OP是想表达这个问题的,比如一个样本表:

m_id | v_id | timestamp
------------------------
6    |   1  | 11
34   |   2  | 12
34   |   3  | 13
6    |   4  | 14
6    |   5  | 15

他想要选择基于**(group bym_id和(order bytimestamp所有列。
那么上面的sql就不能用了,如果你还是不明白,想象一下你的列数比m_id | v_id | timestamp多,比如m_id | v_id | timestamp| columnA | columnB |column C| ...,使用group by,你只能选择那些“group by”列,然后在结果中聚合函数。
到目前为止,你应该已经明白了公认的答案,更重要的是,检查MySQL 8.0中引入的row_number函数:
https://www.mysqltutorial.org/mysql-window-functions/mysql-row_number-function/
1.查找每个组的前N行
它所做的事情与公认的答案相似。
1.有些答案是
错误的**。我的MySQL给我错误。

select m_id,v_id,max(timestamp) from table group by m_id;

@阿比纳什萨胡

SELECT m_id,v_id,MAX(TIMESTAMP) AS TIME
 FROM table_name 
 GROUP BY m_id

@维卡斯·加尔瓦尔
错误信息:

[42000][1055] Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'testdb.test_table.v_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
nukf8bse

nukf8bse7#

为什么搞得这么复杂?这很有效。

SELECT m_id,v_id,MAX(TIMESTAMP) AS TIME
 FROM table_name 
 GROUP BY m_id
xcitsw88

xcitsw888#

你只需要使用ascdesc。编写如下的查询。它将以升序返回值。

SELECT * FROM table GROUP BY m_id ORDER BY m_id asc;

相关问题