SQL sort by desc 不适用于 group by

Posted

技术标签:

【中文标题】SQL sort by desc 不适用于 group by【英文标题】:SQL sort by desc doesn't work with group by 【发布时间】:2021-08-21 09:35:22 【问题描述】:

我试图用tahun和semester列获取最新的id_status列(时间戳都是一样的,所以我不能使用它),我可以用这段代码来做没有问题:

SELECT A.id_ips, B.tahun, B.semester, B.id_status FROM data_ips A
LEFT JOIN data_status_mahasiswa B
ON A.id_mahasiswa = B.id_mahasiswa
ORDER BY B.tahun DESC, B.semester DESC
id_ips tahun semester id_status
155324 2012 2 6
155324 2012 1 7
155324 2009 2 1
155324 2009 1 2
155324 2008 2 9
155324 2008 1 1
155325 2015 2 8
155325 2015 1 3
155325 2010 2 4
155325 2010 1 9
155325 2009 2 9
155325 2009 1 4

但是当我尝试使用列 id_ips 对其进行分组时,数据似乎不再被排序...

SELECT X.* FROM 
(
    SELECT A.id_ips, B.tahun, B.semester, B.id_status FROM data_ips A
    LEFT JOIN data_status_mahasiswa B
    ON A.id_mahasiswa = B.id_mahasiswa
    ORDER BY B.tahun DESC, B.semester DESC
) AS X
GROUP BY X.id_ips
id_ips tahun semester id_status
155324 2008 1 1
155325 2009 1 4

我曾尝试在同一个地方进行 GROUP BY 和 ORDER BY,如下所示:

SELECT A.id_ips, B.tahun, B.semester, B.id_status FROM db_mahasiswa.data_ips A
LEFT JOIN db_mahasiswa.data_status_mahasiswa B
ON A.id_mahasiswa = B.id_mahasiswa
GROUP BY A.id_ips
ORDER BY B.tahun DESC, B.semester DESC

还有这个:

SELECT X.* FROM 
(
    SELECT A.id_ips, B.tahun, B.semester, B.id_status FROM data_ips A
    LEFT JOIN data_status_mahasiswa B
    ON A.id_mahasiswa = B.id_mahasiswa
    ORDER BY B.tahun DESC, B.semester DESC
) AS X
GROUP BY X.id_ips
ORDER BY X.tahun DESC, X.semester DESC

但它仍然产生相同的结果,我想要的是:

id_ips tahun semester id_status
155324 2012 2 6
155325 2015 2 8

不知道问题出在哪里...?

【问题讨论】:

您需要在group by之后的外部查询中放置订单;我不确定mysql,但在其他数据库引擎中,如果没有limittop 子句,order by 将无效。 你为什么使用group by?您没有进行任何聚合。如果您只想要第一行,只需在 ORDER BY 子句后使用 LIMIT 1。 @Stu 结果还是一样... @forpas 数据远不止于此(不同的 id_ips)所以我不能使用限制 您希望我们猜出您的要求是什么吗?编辑您的问题并阐明您想要什么。 【参考方案1】:

这个查询:

SELECT X.*
FROM (SELECT A.id_ips, B.tahun, B.semester, B.id_status
      FROM data_ips A LEFT JOIN 
           data_status_mahasiswa B
           ON A.id_mahasiswa = B.id_mahasiswa
      ORDER BY B.tahun DESC, B.semester DESC
     ) X
GROUP BY X.id_ips;

完全不正确,应该会产生语法错误。为什么?外部查询中的GROUP BY 列与SELECT 列不一致。令人高兴的是,这几乎在所有数据库中都会返回错误。

如果这是你想要的:

我试图用tahun和semester列获取最新的id_status列(时间戳都是一样的,所以我不能使用它)

然后一种方法使用窗口函数:

SELECT X.*
FROM (SELECT A.id_ips, B.tahun, B.semester, B.id_status,
             ROW_NUMBER() OVER (PARTITION BY A.id_ips ORDER BY B.tahun DESC, B.semester DESC) as seqnum
      FROM data_ips A LEFT JOIN 
           data_status_mahasiswa B
           ON A.id_mahasiswa = B.id_mahasiswa
     ) X
WHERE seqnum = 1;

请注意,此查询中根本没有聚合。你没有“聚合”任何东西。你只是想选择正确的行,你通过过滤而不是聚合

【讨论】:

【参考方案2】:

由于您想要每个 id_ips 的 tahun、semester 和 id_status 的最高值,请尝试使用 group by 子句聚合 max()

  SELECT X.id_ips,max(X.tahun) as tahun, max(X.semester) as semester, B.id_status  as id_status FROM 
    (
        SELECT A.id_ips, B.tahun, B.semester, B.id_status,id_mahasiswa FROM data_ips A
        LEFT JOIN data_status_mahasiswa B
        ON A.id_mahasiswa = B.id_mahasiswa
        ORDER BY B.tahun DESC, B.semester DESC
    ) AS X
    left jion data_status_mahasiswa B
    on X.id_mahasiswa = B.id_mahasiswa 

    GROUP BY X.id_ips
    ORDER BY X.tahun 

【讨论】:

抱歉,最新的 id_status 并不总是最大/最大值,如问题表 1 所示(id_status 范围从 1 到 9)。我尝试了另一个答案,它对我有用,顺便说一句,谢谢! 我发现了我的错误并修改了我的答案。但如果您的 MySQL 版本是 8.0,那么 Gordon 的版本肯定是正确的答案。这就是我要求版本的原因。感谢您的投票和最良好的祝愿。【参考方案3】:

您想要的结果的解决方案是不要使用group by,因为您没有聚合任何内容,您只需根据两个后续列的顺序为每个 id_ips 选择一行,其中row_number 是理想的:

with cte as (
    select *, Row_Number() over(partition by id_ips order by tahun desc, semester desc) rn
    from t
)
select id_ips, tahun, semester, id_status
from cte
where rn=1

【讨论】:

以上是关于SQL sort by desc 不适用于 group by的主要内容,如果未能解决你的问题,请参考以下文章

GROUP BY不适用于MySQL 5.7,因为5.7使用SQL_MODE的“ONLY_FULL_GROUP_BY”选项。

SQL里面的order by语句是干啥用的?

SQL注入 order by后的注入(Less-46)

Hive中sort by,order by,cluster by,distribute by总结

sql里的排序倒序的命令是order by啥

sql 排序,order by 按时间