Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql SQL select distinct,但为;保持第一;?_Mysql_Sql - Fatal编程技术网

Mysql SQL select 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是该用户的登录时间戳事件。所以同

根据另一个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是该用户的登录时间戳事件。所以同一个用户(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;