5

I have following data in database

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

How do I group this with select so I get

A C 'comment occurs 3 times

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

gives

A C as well as C A but I want combination combined together.

that it only shows A C 3 times

The example is a mailbox.

This contains:

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 listing should list this (unique conversations)

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

This means this sql will list the messages he have as sender and as receiver (from,to). It should only list between this person and the one sent to no matter who is MAILFROM or MAILTO. timestamp is the date of the latest message between them... Remark he never send to D, a is listed anyhow, to C he sent but didn not get back anything... between B is 3 messages. so output should be only these 3 rows..

4

4 回答 4

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") ;

以下使用caseistead(标准 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
于 2013-07-08T13:05:41.293 回答
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
于 2013-07-08T13:02:17.517 回答
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 邮箱中的字符串中,然后一个简单的选择查找对话从消息顺序中选择邮箱,按时间戳 desc .. 也许它会更快更有效...

于 2013-07-09T09:49:22.757 回答
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)
于 2013-07-08T13:41:02.513 回答