Mysql SQL select distinct,但为;保持第一;?
根据另一个SO post(),distinct在排序方面具有相当未定义的行为 我有一个问题:Mysql SQL select distinct,但为;保持第一;?,mysql,sql,Mysql,Sql,根据另一个SO post(),distinct在排序方面具有相当未定义的行为 我有一个问题: select col_1 from table order by col_2 这可以返回如下值 3 5 3 2 然后,我需要在这些上选择一个保持顺序的不同的,这意味着我想要 select distinct(col_1) from table order by col_2 归来 3 5 2 但不是 5 3 2 这就是我真正想做的。Col_1是用户id,Col_2是该用户的登录时间戳事件。所以同
select col_1 from table order by col_2
这可以返回如下值
3
5
3
2
然后,我需要在这些上选择一个保持顺序的不同的,这意味着我想要
select distinct(col_1) from table order by col_2
归来
3
5
2
但不是
5
3
2
这就是我真正想做的。Col_1是用户id,Col_2是该用户的登录时间戳事件。所以同一个用户(col_1)可以有很多次登录。我正试图建立一个用户的历史列表,在系统中可以看到他们。我想说“我们的第一个用户曾经是,我们的第二个用户曾经是”,等等
这篇文章似乎建议使用GROUPBY,但GROUPBY并不意味着返回行的顺序,因此我不明白这在这里是如何或为什么适用的,因为GROUPBY似乎不会保留任何顺序。事实上,另一篇SO帖子给出了一个示例,其中GroupBy将破坏我正在寻找的顺序:请参阅中的“Peter”。有没有办法保证后一种结果?奇怪的是,如果我实现了DISTINCT子句,我肯定会先执行order by,然后获取结果并对列表进行线性扫描,然后自然保留顺序,因此我不确定为什么行为如此未定义
编辑:
谢谢大家!!我之所以接受IMSoP的答案,是因为不仅有一个我可以玩转的互动示例(感谢您让我使用SQL Fiddle),而且他们还解释了为什么有些事情是按他们的方式工作的,而不是简单地“这样做”。具体来说,还不清楚GROUP BY是否不销毁GROUP BY之外的其他列中的值(而是将它们保存在某种内部列表中),这些值仍然可以在ORDER BY子句中进行检查 我喜欢这样的东西
select col1
from (
select col1,
rank () over(order by col2) pos
from table
)
group by col1
order by min(pos)
在子查询中,我计算位置,然后在主查询中,我对col1进行分组,使用最小的排序位置
这里(这是Oracle,MySql信息是后来添加的
为MySql编辑:
select col1
from (
select col1 col1,
@curRank := @curRank + 1 AS pos
from table1, (select @curRank := 0) p
) sub
group by col1
order by min(pos)
这里。这一切都与SQL语句的“逻辑顺序”有关。尽管DBMS实际上可能会根据各种巧妙的策略检索数据,但它必须根据一些可预测的逻辑进行操作。因此,SQL查询的不同部分可以被视为是在“之前”或“之后”处理的就这种逻辑的行为而言,彼此之间是相互联系的 碰巧,
orderby
子句是该逻辑序列中的最后一步,因此它不能改变“早期”步骤的行为
如果使用分组依据
,则在运行SELECT
子句时,行已被捆绑到它们的组中,更不用说ORDER BY
,因此您只能查看按分组的列,或跨组中所有值计算的“聚合”值。(MySQL实现了您可以在SELECT
中提到逻辑上不存在的列,它将从该组中的任意行中选择一个列)
如果使用DISTINCT
,则在SELECT
之后会对其进行逻辑处理,但是ORDER BY
之后仍然会出现。因此,只有当DISTINCT
丢弃了重复项后,剩余的结果才会被放入特定的顺序中,但是丢弃的行不能用于确定按命令
至于如何获得所需的结果,关键是找到一个值进行排序,该值在运行
分组依据
/DISTINCT
后(逻辑上)是有效的。请记住,如果使用分组依据
,任何聚合值仍然有效-聚合函数可以查看组中的所有值。这包括MIN()
和MAX()
,非常适合按排序,因为“最小数”(MIN
)与“第一个数(如果我按升序排序)”相同,反之亦然
因此,要根据最低适用的bar\u编号
为每个编号订购一组不同的foo\u编号
值,您可以使用以下方法:
SELECT foo_number
FROM some_table
GROUP BY foo_number
ORDER BY MIN(bar_number) ASC
编辑:在评论中,讨论了为什么如果在分组/重复数据消除之前应用了排序,则该顺序不会应用于组。如果是这样,您仍然需要在每个组中保留行的策略:第一行或最后一行 作为类比,将原始的一组行想象为一组从牌堆中挑选的扑克牌,然后按面值从低到高进行排序。现在检查已排序的牌堆,并将其分为每一套牌的单独一堆。哪一张牌应该“代表”每一堆牌 如果你面朝上发牌,最后显示的牌将是面值最高的牌(一种“保持最后”的策略);如果你面朝下发牌,然后翻转每一堆牌,你将显示面值最低的牌(一种“保持第一”的策略)。这两张牌都遵守了牌的原始顺序,并且指示“根据诉讼处理卡”不会自动告诉经销商(代表DBMS的人)计划采用哪种策略
如果最后一堆卡片是
groupby
中的组,则MIN()
和MAX()
表示拾取每一堆并查找最低值或最高值,而不考虑它们的顺序。但是,由于您可以查看组内部,因此您也可以做其他事情,例如将每一堆的总值(SUM
)或有多少张卡(COUNT
)等等,使分组依据
比“有序的不同的
”功能强大得多。参考答案中的分组依据
,并不是试图执行排序……它只是为我们想要不同的列选择一个单一的关联值
喜欢
create table yourTable (
col_1 int,
col_2 int
);
insert into yourTable (col_1, col_2) values (1, 1);
insert into yourTable (col_1, col_2) values (1, 3);
insert into yourTable (col_1, col_2) values (2, 2);
insert into yourTable (col_1, col_2) values (2, 4);
select col_1
from yourTable
group by col_1
order by min(col_2)
SELECT foo_number, bar_number
FROM
(
SELECT foo_number, bar_number
FROM some_table
ORDER BY bar_number
) AS t
GROUP BY foo_number
ORDER BY bar_number DESC;
SELECT
s.NamespaceId,
s.Symbol,
s.EntityName
FROM
(
SELECT
m.NamespaceId,
i.Symbol,
i.EntityName
FROM ImportedSymbols i
JOIN ExchangeMappings m ON i.ExchangeMappingId = m.ExchangeMappingId
WHERE
i.Symbol NOT IN
(
SELECT Symbol
FROM tmp_EntityNames
WHERE NamespaceId = m.NamespaceId
)
AND
i.EntityName IS NOT NULL
ORDER BY LENGTH(i.RawSymbol), i.RawSymbol
) AS s
GROUP BY s.NamespaceId, s.Symbol;