2010-04-17 3 views
2

전체의 여러 테이블 (사용자 그룹)을 선택 유효한 사용자 ID (UID)가 주어지면 지정된 사용자 아이디 (UID)와 동일한 그룹에 속하고 group_member.flag = 3 인 모든 사용자의 아이디를 가져옵니다.SQL의 문제는 이런 식으로 뭔가를 보이는 DB 스키마를

그냥 SQL이 있어야합니다. 나는 Db 프로그래머처럼 생각하는 법을 배우고 싶다. 코더로서, SQL은 필자의 가장 약한 링크입니다 (선언적 언어보다 명령 언어에 훨씬 더 익숙하기 때문에).하지만 저는 그것을 바꾸고 싶습니다.

어쨌든 다음은 작업을 분류하는 데 필요한 단계입니다. SQL 전문가가 단순한 SQL 문 (즉, 원자 SQL 문, 아래에 식별 된 하위 타스크에 대해 각각 하나씩)을 보여줄 수 있다면 마침내 나는이 문을 결합하여 필요한 기능을 구현하는 ONE 문을 어떻게 만들 수 있는지에 대해 감사하게 생각합니다. 내가 subtask2에 대한 SQL이 있으면, 그때 싶습니다

//Subtask #1. 
Fetch list of all groups of which I am a member 

Select group.id from user inner join group_member where user.id=group_member.user_id and user.id=1 

//Subtask #2 
Fetch a list of all members who are members of the groups I am a member of (i.e. groups in subtask #1) 

Not sure about this ... 

select user.id from user, group_member gm1, group_member gm2, ... [Stuck] 

//Subtask #3 
Get list of users that satisfy criteria group_member.flag=3 
Select user.id from user inner join group_member where user.id=group_member.user_id and user.id=1 and group_member.flag=3 

이 (전체 SQL 문이 하위에서 구축 방식을 볼 수 : 여기

은 (지정된 USER_ID [UID]를 가정 = 1) 간다 당신은 서브 타스크에서 SQL을 사용하지 않아도됩니다. 이것은 관련된 단계를 설명하는 방법 일뿐입니다. 또한 SQL은 정확하지 않을 수 있습니다. 그렇다면 수정하십시오. .

감사합니다.

+1

는'foobar_id'이 멤버의 그룹 ID는 무엇입니까? 또한 사용중인 데이터베이스 엔진은 무엇입니까? MySQL, SQLite, PostgreSQL, ...? –

+0

Doh! – morpheous

답변

6

쿼리 1 - 내가 속한 모든 그룹을 선택하십시오.

그룹의 이름도 필요하지 않으면 여기에서 조인 할 필요가 없습니다. group_member 표를 확인하세요.

SELECT group_id 
FROM group_member 
WHERE user_id = 1 

결과 :

1 
3 

쿼리 2 : 저와 같은 그룹 중 하나에 모든 사용자를 선택합니다.

group_member 테이블을 자체 조인하여 서로 동일한 그룹에있는 모든 사용자를 찾은 다음 where 절을 추가하여 자신과 같은 그룹에있는 모든 사용자 만 찾을 수 있습니다. DISTINCT을 추가하여 사람들이 두 번이나 몰리지 않도록하십시오.

SELECT DISTINCT T2.user_id 
FROM group_member AS T1 
JOIN group_member AS T2 
ON T1.group_id = T2.group_id 
WHERE T1.user_id = 1 
AND T2.user_id <> 1 -- Remove myself 

결과 :

2 
3 
5 

쿼리 3 : 모든 그룹에서 플래그 3이 사용자.

group_member 테이블을 확인하기 만하면됩니다. 각 사용자를 한 번만보고 싶으면 DISTINCT을 다시 입력하십시오.

SELECT DISTINCT user_id 
FROM group_member 
WHERE group_member.flag=3 

결과 :

2 
3 
4 

는 최종 쿼리 :이 거의 쿼리 두과 동일 3.

플래그가 저와 같은 그룹의 사용자는 단지 여분의 추가 어디 조건.

SELECT DISTINCT T2.user_id 
FROM group_member AS T1 
JOIN group_member AS T2 
ON T1.group_id = T2.group_id 
WHERE T1.user_id = 1 
AND T2.user_id <> 1 -- Remove myself 
AND T2.flag = 3 

결과 :

2 
3 

테스트 데이터 : I 가정

create table user   (id int, name varchar(32)); 
create table `group`  (id int, name varchar(32)); 
create table group_member (group_id int, user_id int, flag int); 

insert into user (id, name) VALUES (1, 'user1'), (2, 'user2'), (3, 'user3'), (4, 'user4'), (5, 'user5'); 
insert into `group` (id, name) VALUES (1, 'group1'),(2, 'group2'), (3, 'group3'); 
insert into group_member (group_id, user_id, flag) VALUES (1, 1, 0), (1, 2, 3), (1, 3, 3), (2, 3, 3), (2, 4, 3), (2, 5, 0), (3, 1, 0), (3, 5, 0); 
+0

@Mark : 명확하고 자세한 답변을 주셔서 대단히 감사합니다. 나는 신중하게 그것을 공부할 것이고, 더 이상의 질문이 있으면, 나는 당신이 내가 묻는 것을 염려하지 않기를 바란다. 나는이 질문을 받아 들일 것이다 (나는 아직 투표를하기에 충분한 점수가 없다) – morpheous

-1

SQL의 장점은 이러한 세 가지 선택을 하나의 효율적인 결합으로 결합 할 수 있다는 것입니다. 이 경우에는 쉽게 이해할 수 있기 때문에 조인의 WHERE 버전을 사용했습니다. 그러나 LEFT JOIN과 INNER JOIN 문법은 표현력이 풍부하기 때문에 구문을 살펴볼 수도 있습니다.

SELECT * FROM user, group_member, group 
WHERE user.id = group_member.user_id 
&& group_member.group_id = group.id 
&& group_member.flag = 3 
+3

고칠 것입니다 어떤 SQL 버전이 "&&"에 대한 "AND"대체가 될까요? 나는 그것을 본 적이 없다. – MJB

+0

아, 제 잘못입니다. 오래된 MySQL입니다. 그러나 그것은 여전히 ​​효과가 있습니다. 단지 자주 보지 못합니다. –

+1

-1. 나는 이것이 질문이 묻는 것을하지 않는다고 확신한다. 3 개의 테이블을 결합한 다음 '플래그 = 3'인 사용자를 선택합니다. 내가 이해할 수있는 한 질문은 특정 사용자와 동일한 그룹에 속한 모든 사용자를 찾을 수있는 방법을 찾고 있습니다. (깃발 = 3을 가지고 있습니다.) –

2

특정 사용자와 동일한 그룹의 모든 사용자를 지정된 플래그로 찾아야합니다.

SELECT DISTINCT g2.user_id 
FROM group_member AS g INNER JOIN group_member AS g2 
    ON g.group_id = g2.group_id 
WHERE g.user_id = <the userid you want to find> 
    AND g2.flag = 3 

이 문제에 접근하기 위해, 나는 한 다음 우리는 같은 그룹에있는 사람을 알고 원하는

우리는 두 group_member들 비교해야, 그래서 우리는 group_member에 가입해야합니다 그 자체로. (group_id에, 우리는 같은 그룹에있는 것들을 원합니다.)

그 중 하나가 내가 비교하고 싶은 사용자이고 다른 하나가 올바른 플래그를 가지고 있어야합니다.

일단 완료되면 원래 사용자와 비교했을 때 user_id을 꺼내기 만하면됩니다. 사용자가 다른 사용자가 속한 두 그룹에 속할 수도 있으므로, DISTINCT을 추가하면 각자 user_id을 한 번만 빼낼 수 있습니다.

+0

@Sebastian : SQL Poetry !. 이 문제를 해소 할 수 있습니까? (나는 그것을 적어 놓은 것을 이제는 이해할 수 있음을 의미합니다.)하지만 어떻게 접근했는지 배우고 싶습니다. 어떻게 문제를 해결 했습니까? 제가 설명했던 것과 비슷한 단계를 사용 했습니까? 나는 경험 많은 SQL 사람들에게 솔루션을 "보았"만한다는 것을 알고 있습니다 - 아직 거기에 없기 때문에 논리적이고 수동으로 접근해야합니다. – morpheous

+0

나는 그가 요구 한 것이 당신의 어디서의 상태가 아닌가 생각합니다. –

+0

@Mark : 나는'g2' 대신에'g'를 실제로 했어! @morpheous : 나는 내 생각을 약간 설명하려고 노력했다. –

관련 문제