5

データベースに次のデータがあります

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でグループ化して取得するにはどうすればよいですか

AC'コメントが3回発生

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

与える

ACもCAもいいけどコンビを組んで欲しい。

ACが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が送信者および受信者(from、to)として持っているメッセージをリストすることを意味します。誰が MAILFROM か MAILTO かに関係なく、この人と送信された人との間でのみリストする必要があります。タイムスタンプは、それらの間の最新のメッセージの日付です...彼はDに送信しないことに注意してください.aはとにかくリストされています.Cに送信しましたが、何も返されませんでした... B間は3つのメッセージです. したがって、出力はこれらの3行のみである必要があります..

4

4 に答える 4

4

least()多くのデータベースがand関数をサポートしてい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") ;

以下はcaseisntead (標準 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

これが解決策でした

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 スタイルのメールボックスとしても知られています。これが効率的かどうかはわかりませんが、2 人のユーザー間で独自のメールボックスを持つ方がよいかもしれません。A_B と B_A には独自のものがあり、A が B に書き込むと、メッセージが A_B と B_A のメールボックスの文字列に追加され、簡単な選択で会話を検索し、タイムスタンプの順序でメッセージからメールボックスを選択します。 ...

于 2013-07-09T09:49:22.757 に答える
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 に答える