【问题标题】:Issue with SQL query when using DISTINCT and ORDER BY使用 DISTINCT 和 ORDER BY 时出现 SQL 查询问题
【发布时间】:2012-08-29 04:16:11
【问题描述】:

给定一个名为 Messages 的数据库表,其中包含以下列:-

MessageID, FromUser, ToUser, Message, DateTime

我想编写一个 SQL 查询,为“FromUser”列选择不同的值,但我也想要按 DateTime 排序的值。

本质上是一个查询,例如:

SELECT * FROM Messages WHERE ToUser='1' ORDER BY DateTime DESC

然后,使用以下内容选择不同的 FromUser:

SELECT DISTINCT FromUser FROM Messages WHERE ToUser='1'

同时,保持上一个查询的顺序。

我曾尝试使用嵌套查询,但遇到了一个问题,因为您无法在内部查询中使用 ORDER BY。

本质上,我希望查询的语法表示(这是无效的,但是...):

SELECT DISTINCT FromUser FROM Messages WHERE ToUser=1 AND FromUser IN 
(SELECT * FROM Messages WHERE ToUser=1 ORDER BY DateTime DESC)

【问题讨论】:

  • 每个唯一的 FromUser 可以有多个候选日期,因此您需要一些聚合...您想要哪个日期,max()?
  • 这里的问题是,如果 FromUser 在 Messages 表中以不同的时间出现多次怎么办。它们应该出现在列表的什么位置?
  • 我正在尝试找出您想要的输出的原因。如果您发布一些虚假数据和预期输出,我很可能会在这里得到快速回复。
  • @rs - 您的查询不起作用(之前尝试过),因为当 DateTime 不在 select 语句中时,它无法按 DateTime 排序。
  • @AlexK。 - 是的,我想选择日期的最大值。

标签: sql sql-server sql-server-2008 tsql


【解决方案1】:

我猜这就是你需要的:

;WITH CTE AS
(
    SELECT *, ROW_NUMBER() OVER(PARTITION BY [FromUser] ORDER BY [DateTime] DESC) RN
    FROM [Messages]
    WHERE ToUser='1' 
)
SELECT *
FROM CTE
WHERE RN = 1

【讨论】:

    【解决方案2】:

    所以在你的select 语句中包含DateTime,或者按它分组,或者使用聚合函数之一,例如MAX(),例如:

        Select fromuser, datetime
        from messages
        where touser = '1'
        group by 
        fromuser, datetime
        order by 
        fromuser, datetime
    

    Select fromuser, max(datetime) as max_datetime
    from messages
    where touser = '1'
    group by 
    fromuser
    

    【讨论】:

      【解决方案3】:

      您将为每个 FromUser 设置多个时间戳。我将假设您想为每个人使用最后一个时间戳。

      select * 
      from Messages join 
          (select fromuser, MAX(datetime) as lastdate from Messages
          group by FromUser) as abb1 on abb1.FromUser = messages.FromUser and abb1.lastdate = messages.Datetime
      where ToUser = '1'
      order by Datetime desc
      

      【讨论】:

        【解决方案4】:
        SELECT DISTINCT [Messages].[FromUser] FROM (
        SELECT [FromUser] as [FromUser], MAX(DateTime) as [Date]
        FROM [Messages]
        GROUP BY [FromUser]) as [Messages]
        

        【讨论】:

          【解决方案5】:

          另一种方式;

          select * from
          (
              select *, max(DateTime) over (partition by FromUser) newest
              from Messages
          ) T
          where DateTime = newest
          

          (如果同一个人的日期相同,则为 n 行)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-11-17
            相关资源
            最近更新 更多