-1

我正在制作一个系统,其中有一个同时发生的情况,例如假设用户 1 单击用户 2 的按钮并且两个用户的名称都保存在数据库中,并且如果用户 2 也单击用户 1 按钮(其中用户 2 是同一个用户用户 1 点击,在第二种情况下,用户 1 与在第一种情况下点击用户 1 的用户相同)。那么如何过滤掉这两个互相给予动作的用户呢?

user 1  user 2 action 

 frank  ron     1

  ron  frank    1  

这样它就表明存在巧合,因为两者都相互采取行动

4

1 回答 1

1

有几种方法可以做到这一点。

由于您没有提供任何 SQL DDL,我将添加一些。(将来包括 DDL。你会得到更多的答案。)

create table test (
  user_1 varchar(15) not null,
  user_2 varchar(15) not null,
  action integer not null,
  primary key (user_1, user_2, action)
);

insert into test values
('frank', 'ron', 1),
('ron', 'frank', 1  );

-- This is a one-way action. It should be excluded from the results.
insert into test values
('ron', 'fred', 1);

insert into test values
('ron', 'fred', 2),
('fred', 'ron', 2);

这将为每个匹配返回成对的行。这不是表达此查询的特别好方法,因为这些对不会直接排序在一起。

select t1.user_1, t1.user_2, t1.action
from test t1
inner join test t2 
        on t2.user_1 = t1.user_2 
       and t2.user_2 = t1.user_1
       and t2.action = t1.action

USER_1    USER_2  ACTION
--
frank     ron       1
fred      ron       2
ron       frank     1
ron       fred      2

如果您尝试对该结果集进行排序,您最终可能会得到很多介于“frank”和“ron”之间的名称。很难看出这些数据有正确的答案。

此查询为每个匹配对返回一行。

select user_1, user_2, action
from test
where user_1 < user_2
union all 
select user_2, user_1, action
from test 
where user_2 < user_1
group by user_1, user_2, action
having count(action) = 2

USER_1  USER_2  ACTION
frank   ron      1
fred    ron      2

它创建原始表的两个真子集的并集。在每一行中,第一列“小于”第二列。这具有制造重复行的效果。重复的行意味着每个用户已经“操作”了另一个。GROUP BY 和 HAVING 子句消除了单向操作。

于 2013-05-10T17:04:31.077 回答