如何分组SQL结果

时间:2013-07-08 12:35:33

标签: mysql sql

我在数据库中有以下数据

MAILFROM, MAILTO , TIMESTAMP, MESSAGE
A B   2013-07-01 12:11:12, Hi
B A   2013-07-01 12:12:12, Hi back
A B   2013-07-01 12:13:12, How are you
A C   2013-07-01 12:14:12, Hi there
D A   2013-07-01 12:16:12, Hi
C D   2013-07-01 12:17:12, Hi

如何将其与select分组,以便

C'评论发生3次

SELECT MAILFROM, MAILTO FROM messages WHERE 'A' IN(FROM,TO) GROUP BY FROM

给出

A C. 以及 C A但我希望组合在一起。

它只显示A C 3次

示例是邮箱。

包含:

MAILFROM, MAILTO , TIMESTAMP, MESSAGE
A B   2013-07-01 12:11:12, Hi
B A   2013-07-01 12:12:12, Hi back
A B   2013-07-01 12:13:12, How are you
A C   2013-07-01 12:14:12, Hi there
D A   2013-07-01 12:16:12, Hi
C D   2013-07-01 12:17:12, Hi

SQL列表应列出此(唯一对话)

B   2013-07-01 12:13:12, "Hi"  ' Remark Timestap of the latest message
C   2013-07-01 12:14:12, "Hi there"
D   2013-07-01 12:16:12, "Hi"
C D   2013-07-01 12:17:12, "Hi" ' THIS SHOULD NOT BE SHOWN

这意味着这个sql会列出他作为发送者和接收者(从,到)的消息。它应该只列在这个人和发送给谁的人之间,无论谁是MAILFROM或MAILTO。时间戳是他们之间最新消息的日期...备注他永远不会发送到D,无论如何都列出了一个,但是他发送但没有得到任何东西...... B之间是3条消息。所以输出应该只有这3行..

4 个答案:

答案 0 :(得分:4)

许多数据库支持least()greatest()函数。你可以做你想做的事情:

select least("from", "to") as party1,
       greatest("from", "to") as party2,
       count(*) as NumMessages,
       max(timestamp) as maxtimestamp
from messages
group by least("from", "to"), greatest("from", "to") ;

以下使用case isntead(标准SQL),并且应该适用于大多数数据库:

select (case when "from" < "to" then "from" else "to" end) as party1,
       (case when "from" < "to" then "to" else "from" end) as party2,
       count(*) as NumMessages,
       max(timestamp) as maxtimestamp
from messages
group by (case when "from" < "to" then "from" else "to" end),
         (case when "from" < "to" then "to" else "from" end)

编辑:

如果您希望将此作为给定人员的唯一消息:

select (case when "from" = const.ThePerson then "to" else "from" end) as Other,
       count(*) as NumMessages,
       max(timestamp) as maxtimestamp
from messages m cross join
     (select 'A' as ThePerson) const
where const.ThePerson in ("from", "to")
group by "from", "to";

要获取最后一条消息,您需要加入原始数据:

select Other, NumMessages, MaxTimeStamp, m.message
from (select (case when "from" = const.ThePerson then "to" else "from" end) as Other,
             count(*) as NumMessages,
             max(timestamp) as maxtimestamp,
             max(ThePerson) as ThePerson,
      from messages m cross join
           (select 'A' as ThePerson) const
      where const.ThePerson in ("from", "to")
      group by "from", "to"
     ) t join
     messages m
     on m."from" in (t.Other, t.ThePerson) and
        m."to" in (t.Other, t.ThePerson) and
        m.TimeStamp = t.maxtimestamp

答案 1 :(得分:0)

我创建了另一个包含from1和to1

字段的表
SELECT from1, to1 FROM messages
WHERE (from1 LIKE 'A' AND to1 LIKE 'C') OR (from1 LIKE 'C' AND to1 LIKE 'A')

输出

A C
C A
A C

答案 2 :(得分:0)

select distinct (FROM+TO) as ans from messages 

在MySQL中

select distinct CONCAT(FROM, '', TO) as ans from messages 

select CONCAT(FROM, '', TO) as ans from messages group by CONCAT(FROM, '', TO)

答案 3 :(得分:0)

好的,这是解决方案

select mailfrom, mailto,timestamp from (select MAILFROM,MAILTO,timestamp  from messages union all select MAILTO,MAILFROM,timestamp from messages order by timestamp desc) as MSG where MSG.mailfrom='A' group by MSG.mailto order by bb.timestamp desc

感谢您的时间和帮助,也知道Facebook的邮箱风格。我不知道这是否有效,也许在两个用户之间拥有自己的邮箱会更好。 A_B和B_A有自己的,当A写入B然后消息被添加到A_B和B_A邮箱中的字符串,然后一个简单的选择查找会话按消息顺序选择邮箱按时间戳描述..也许它会更快更有效...