2012-09-27 35 views
4

我在我的網站上有一個個人消息系統,非常簡單。 但我想有一個管理員頁面,其中所有會話都顯示在用戶和他們的消息量之間。如何在SQL中的兩列進行交叉分組?

所以表看起來像(簡體版):

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個消息

這在我的表中的所有用戶同時。

我真的停留在這,我到處搜索,但還沒有找到解決方案。 困難在於,我希望所有用戶列出,我必須以某種方式跨越「從」和「到」列...

我希望任何人都能夠提供幫助。 在此先感謝。

回答

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 
+0

太謝謝你了!你讓我今天一整天都感覺很好! :) – LMoeyaert

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 
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 
相關問題