通过mysql选择组中的唯一值(基于两列)

时间:2015-04-11 05:50:18

标签: mysql sql

我是SQL新手。 我在MySQL中编写了以下查询

select * from msgs where (msgs.toid = 1 or msgs.fid = 1) group by fid,toid;

此查询返回如下所示的值。

|message_id | toid | fid |
    68          4     1 
    70          1     9
    72          1     4
    78          5     1
    80          9     1

我的预期结果应为

|message_id | toid | fid |
    72          1     4
    78          5     1
    80          9     1

这意味着我不应该重复值(基于两列值toid,fid),它应该是最高的id值。

toid和fid的组合应该是唯一的。

4 个答案:

答案 0 :(得分:2)

您可以使用greatest(),least()检查是否存在具有相同ID和更高消息ID组合的另一行(这意味着所选行具有给定组合的最高消息ID)。

select * from msgs m where (toid = 1 or fid = 1)
and not exists (
    select 1 from msgs m2
    where greatest(m2.toid,m2.fid) = greatest(m.toid,m.fid)
    and least(m2.toid,m2.fid) = least(m.toid,m.fid)
    and m2.message_id > m.message_id
)

编辑 - 使用row_number()

的另一种方式
select * from (
    select * , 
        row_number() over (partition by greatest(toid,fid),
          least(toid,fid) order by message_id desc) rn
    from msgs m where (toid = 1 or fid = 1)
) t1 where rn = 1

答案 1 :(得分:0)

你也可以试试这个。

select * from msgs m 
        where (toid = 1 or fid = 1)
          and not exists ( select 1 from msgs m2
                                   where (m2.toid + m2.fid) = (m.toid + m.fid)
                                     and m2.message_id > m.message_id
                         )

答案 2 :(得分:0)

SELECT *
FROM msgs m
WHERE NOT EXISTS (  SELECT 'a'
                    FROM msgs m2
                    WHERE m2.msg_id > m.msg_id
                    AND (
                          (  m.toid = m2.toid
                             AND m.fid = m2.fid
                          )
                        OR ( m.toid = m2.fid
                             AND m.fid = m2.toid
                          )
                        )
                   )
AND (m.toid = 1 OR m.fid = 1)

返回两个用户之间对话的最后消息

答案 3 :(得分:0)

您可以使用此查询:

SELECT
  MAX(message_id) AS message_id,
  LEAST(toid, fid) AS toid,
  GREATEST(toid, fid) AS fid
FROM
  msgs
GROUP BY
  LEAST(toid, fid) AS toid,
  GREATEST(toid, fid) AS fid

是的,它会返回例如

80    1    9

而不是

80    9    1

但由于(1,9)相当于(9, 1),因此它应该不是问题。如果是,请参阅FuzzyTree的答案。