2013-05-10 57 views
-1

我正在製作一個系統,其中有一個共同點,例如,假設用戶1單擊user2的按鈕,並且兩個用戶的名稱都保存在數據庫中,並且if用戶2也點擊用戶1按鈕(其中用戶2是與用戶1點擊的用戶相同的用戶,並且第二情況下用戶1是與在第一情況下點擊用戶1的用戶相同的用戶)。那麼如何過濾掉兩個互相作用的用戶呢?sql查詢獲取兩個用戶之間的共犯行爲

user 1 user 2 action 

frank ron  1 

    ron frank 1 

,使得它告訴有一個巧合,因爲這兩個動作給彼此

+0

SELECT * FROM my_table x JOIN my_table y ON y.something = x.something_else AND y.something_else ...哦,你明白了... – Strawberry 2013-05-10 16:40:26

+0

他們不是兩個不同的表,而是一個表 – user1001176 2013-05-10 16:51:10

+0

你的觀點是。 ..? – Strawberry 2013-05-10 16:52:29

回答

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 

如果你想那種結果集,你可以有很多「坦率」和「羅恩」之間的名稱結束。很難看到這些數據有正確的答案。

此查詢爲每個匹配對返回一行。

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子句消除了單向行爲。

+0

我試了第二個,它似乎並不工作 – user1001176 2013-05-10 18:12:09

+0

它的工作原理。 [SQLfiddle在這裏](http://www.sqlfiddle.com/#!2/dcb9a/1)。 – 2013-05-10 18:22:14