在选择了多个列的SELECT中使用Distinct(col)

时间:2016-11-17 18:04:58

标签: sql

我的目标是返回一个不同的'mFrom'列表,只从'messages'表中提取最新的'date'。

Table: messages
id     mFrom     mTo   date
--     -----     ---   ----
int    int       int   datetime

我正在尝试使用此查询:

SELECT DISTINCT(mFrom), date FROM messages WHERE mTo = '116'

但是我收到了这些结果:

mFrom   date
9     | 2016-11-17 00:30:03
11    | 2016-11-17 12:35:08
11    | 2016-11-17 12:35:35

我希望看到这些结果......

mFrom  date
9     | 2016-11-17 00:30:03
11    | 2016-11-17 12:35:35

感谢任何帮助。使用GROUP BY和内部SELECT看到类似的答案,但是在为我的特定字段提出类似的查询时遇到了麻烦..

3 个答案:

答案 0 :(得分:7)

GROUP BY似乎是对的。

SELECT mFrom, MAX(date) as date 
FROM messages 
WHERE mTo = '116' 
GROUP BY mFrom

答案 1 :(得分:0)

我们假设您有更多在游戏中独一无二的列,例如:你想要mFrom的最新消息,但你也想要mTo。然后你应该考虑一个分区的行号。对于例如系统支持Windows功能的sql-server通常会有一个ROW_NUMBER()函数可以使用。以下是使用公用表表达式[CTE]和ROW_NUMBER()的示例。注意使用RANK()或DENSE_RANK()代替将允许绑定。

;WITH cte AS (
    SELECT *
       ,ROW_NUMBER() OVER (PARTITION BY mFrom ORDER BY Date DESC) as RowNumber
    FROM
       Messages
    WHERE
       mTo = 116
)

SELECT *
FROM
    cte
WHERE
   RowNumber = 1

在我的sql中,这变得更加复杂,您可以通过使用变量来实现:

SELECT *
FROM
    (
       SELECT
          m.*
          ,(@rn:= if(@mFrom = mFrom, @rn + 1, 
                if(@mFrom:=mFrom, 1, 1)
                )) as RowNumber
       FROM
          Messages m
          CROSS JOIN (SELECT @mFrom:=0, @rn:=0) var
       WHERE
          mTo = 116
    ) t
WHERE
    t.RowNumber = 1

或者在任一系统中,您都可以使用Gareth显示的GROUP BY技术并将其与原始表关联,或者IN或EXISTS如果mFrom的2条消息共享相同的MAX(日期),则所有这些方法将返回关联。这是一个加入的例子。

SELECT *
FROM
    Messages m
    INNER JOIN (SELECT mFrom, MAX(date) as date
             FROM
                Messages
             WHERE
                mTo = 116
             GROUP BY
                mFrom) t
    ON m.mFrom = t.mFrom
    AND m.date = t.date
WHERE
    mTo = 116

答案 2 :(得分:-1)

11 | 2016-11-17 12:35:08
11 | 2016-11-17 12:35:35

你可以看到日期时间字段,时间关闭几秒钟。

你可以这样做,

SELECT DISTINCT(mFrom), cast(date as date) FROM messages WHERE mTo = '116'

这将删除时间并给你

mFrom date
9 | 2016-11-17 
11 | 2016-11-17