2012-09-27 29 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 
相关问题