SQL:如何使用 DISTINCT 保持行顺序?
以下 SQL 查询:
SELECT messages.id, messages.created_at, comments.created_at FROM messages
LEFT JOIN comments ON comments.message_id = messages.id
WHERE (messages.id IN (429,443))
ORDER BY GREATEST(messages.created_at, comments.created_at) DESC
返回:
id messages.created_at comments.created_at
--------------------------------------------------------
443 2 5
429 1 4
443 2 3
(I replaced dates with numbers for readability)
仅在添加 DISTINCT
后获取每个 id
:
SELECT DISTINCT messages.id FROM messages
LEFT JOIN comments ON comments.message_id = messages.id
WHERE (messages.id IN (429,443))
ORDER BY GREATEST(messages.created_at, comments.created_at) DESC
但是,在结果中 id
值更改了顺序:
id
---
429
443
什么可能是原因吗?
我怎样才能保留订单?
The following SQL query:
SELECT messages.id, messages.created_at, comments.created_at FROM messages
LEFT JOIN comments ON comments.message_id = messages.id
WHERE (messages.id IN (429,443))
ORDER BY GREATEST(messages.created_at, comments.created_at) DESC
returns:
id messages.created_at comments.created_at
--------------------------------------------------------
443 2 5
429 1 4
443 2 3
(I replaced dates with numbers for readability)
To get each id
only once I added DISTINCT
:
SELECT DISTINCT messages.id FROM messages
LEFT JOIN comments ON comments.message_id = messages.id
WHERE (messages.id IN (429,443))
ORDER BY GREATEST(messages.created_at, comments.created_at) DESC
But, in the result the id
values changed order:
id
---
429
443
What could be the reason for that ?
How could I keep the order ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
distinct
关键字正在做它应该做的事情,每行返回一个给定的列值。 Distinct 不允许您指定将返回哪一行,并且从原始查询中可以清楚地看出,允许这样的排序(id 为 443 的行后面有 id 为 429 的行) )。要控制将返回哪些行,您需要重新构造查询。我将采取的典型解决方案是使用
group by
,从每个组中选择组列和所需的行,其效果是如果我需要做更多,我将使用这个将查询排序为较大查询中的子选择,可能会连接 id 字段以从首选行中获取更多字段,或者以特定方式对查询进行排序。
the
distinct
key word is doing what it's supposed to do, return one row each with a given column value. Distinct doesn't allow you to specify which such row will be returned, and it's clear from the original query that such an ordering is allowed (there is a row with id 443 that follows a row with id 429).To take control of what rows will be returned, you need to reformulate the query. A typical solution I'll take is to use a
group by
, selecting the group column and the desired row from each group, something to the effect ofIf I need to do more, I'll use this sort of query as a subselect in a larger query, possibly joining on the id field to get more fields from the preferred row, Or ordering the query in a particular way.