4

私のウェブサイトには個人的なメッセージ システムがありますが、これは非常に簡単です。しかし、ユーザー間のすべての会話とそのメッセージの量が表示される管理者ページが必要です。

したがって、表は次のようになります (簡略版):

CREATE TABLE pm (
    id        INT(10)     NOT NULL AUTO_INCREMENT,
    from      INT(10)     NOT NULL REFERENCES (usertable),
    to        INT(10)     NOT NULL REFERENCES (usertable),
    message   BLOB        NOT NULL
);

例:

マーク、ジョン、ブライアン、ケイトのユーザーがいるとします。

Mark (from) は John (to) に 5 つのメッセージを送信し、John (from) は Mark (to) に 3 つのメッセージを送信します。

Kate (from) は 2 つのメッセージを Bryan (to) に送信し、Bryan (from) は 1 つのメッセージを Kate (to) に送信します。

を示す結果セットが欲しい

マーク - ジョン - 8 メッセージ

ケイト - ブライアン - 3 メッセージ

そして、これは私のテーブル内のすべてのユーザーに対して一度に行われます。

私は本当にこれに行き詰まっており、どこでも検索しましたが、解決策が見つかりませんでした。難しさは、すべてのユーザーをリストしたいという事実にあり、「from」と「to」の列をどうにか交差させなければなりません...

誰でも助けてくれることを願っています。前もって感謝します。

4

3 に答える 3

3
select from_id, to_id, count(*) count_between
from
(
    select from_id, to_id from pm
    union all
    select to_id, from_id from pm
) combined
where from_id < to_id
group by from_id, to_id

完全なサンプル

CREATE TABLE pm (from_id int,to_id int);
insert pm select 1,2;
insert pm select 1,2;
insert pm select 1,2;
insert pm select 1,2;
insert pm select 1,2;
insert pm select 2,1;
insert pm select 2,1;
insert pm select 2,1;
insert pm select 3,4;
insert pm select 3,4;
insert pm select 4,3;

select from_id, to_id, count(*) count_between
from
(
    select from_id, to_id from pm
    union all
    select to_id, from_id from pm
) combined
where from_id < to_id
group by from_id, to_id

--- results
from_id     to_id       count_between
----------- ----------- -------------
1           2           8
3           4           3

ID を名前に変換するには、user表への法線などを使用します。例えば

select u1.name from_, u2.name to_, count(*) count_between
from
(
    select from_id, to_id from pm
    union all
    select to_id, from_id from pm
) combined
join users u1 on u1.id = combined.from_id
join users u2 on u2.id = combined.to_id
where from_id < to_id
group by u1.name, u2.name
于 2012-09-27T06:39:18.293 に答える
0

最大の ID を持つ人を最初にリストすることで、会話ペアを一意にすることができます。次に、両方の人物の ID でグループ化できます。

select  ut1.name
,       ut2.name
,       convo_pairs.message_count
from    (
        select  case when [from] < [to] then [to] else [from] end as p1
        ,       case when [from] < [to] then [from] else [to] end as p2
        ,       count(*) as message_count
        from    pm
        group by
                case when [from] < [to] then [to] else [from] end as p1
        ,       case when [from] < [to] then [from] else [to] end as p2
        ) as convo_pairs
join    usertable ut1
on      ut1.id = convo_pairs.p1
join    usertable ut2
on      ut2.id = convo_pairs.p2
于 2012-09-27T06:35:11.740 に答える
0

これを試して

select ISNULL(a.from,b.from) + '-' + ISNULL(a.to,b.to) + '-' +  convert(varchar(a.count+b.count)) + 'messages' 
(select pm1.from,pm1.to,count(1) count
from pm pm1
group by pm1.from,pm1.to) a FULL OUTER 
(select pm1.from,pm1.to,count(1) count 
from pm pm1
group by pm1.from,pm1.to) b
on a.from=b.to
and a.to=b.from
于 2012-09-27T06:41:47.023 に答える