2012-03-22 4 views
0

일부 MySQL 조인을 사용하고 있지만이 중 하나는 다소 혼란 스럽습니다. 나는 3 개의 테이블 friends, postsactivity을 가지고 있습니다.INNER JOIN이있는 MySQL SELECT 2 테이블

postsactivity에는 모두 해당 레코드가 속한 사용자를 나타내는 userid 필드가 있습니다. friends에는 친구가되는 두 명의 사용자를 나타내는 useridfriendid 필드가 있습니다.

가능한 경우 로그인 한 사용자와 친구 인 사용자의 postsactivity에있는 레코드를 표시 할 쿼리를 설계하고 싶습니다. 나는 위의 쿼리를 실행할 때

SELECT p.*, a.* 
    FROM posts AS p, activity AS a 
    INNER JOIN friends f ON (p.userid = f.friendid) 
    WHERE f.userid = '(Logged In User ID)' 

그러나, 나는 다음과 같은 오류 얻을 :

나는 다음과 같은 쿼리를 시도 어떤 도움이 많이 주시면 감사하겠습니다

Unknown column 'p.userid' in 'on clause'

을 :)

+0

괄호 안에 테이블에서 퍼팅보십시오 : 'FROM (AS AS, AS 활동) '. – Straseus

+0

게시물과 p 사이의 AS를 제거하십시오. 활동과 a 사이에 동일하게 간다. 그리고 당신은 p.userid = f.friendid + 주위에 괄호가 필요하지 않습니다. cascadian 제품은 불가피합니다 그래서 활동과 다른 두 테이블 사이의 관계가 없습니다 – GuZzie

답변

4

아마도 UNION이 필요합니다. 두 테이블 (postsactivity)이 같은 수의 열 (순서가 같고 비슷한 유형) 인 경우 다음이 작동합니다. 그렇지 않은 경우, 일부 조정은 SELECT 목록에 필요 :

SELECT p.id 
    , p.userid 
    , p.post_text  AS text 
    , p.post_date  AS date 
    , NULL   AS action 
    FROM posts AS p 
    ... 
UNION ALL 
SELECT a.id 
    , a.userid 
    , NULL   AS text 
    , a.activity_date AS date 
    , a.action  AS action 
    FROM activity AS a 
    ... 
+0

도와 줘서 고마워, 두 테이블 다른 분야가 있습니까? 'activity'는'posts'에서 8 개 필드와 5 개 필드를 가지고 있으며, PRIMARY 키와 userid를 제외하고 필드는 완전히 완전히 다릅니다. – Jamie

+0

짧은 대답은 아니오입니다. 아마도 오랜 대답 일 겁니다. 경우에 따라보기를 사용하여 결과를 사용자에게 보낼 수있는 것처럼 보이는 단일 데이터 세트로 매핑 할 수 있습니다. 여전히 매우 다르다면 애플리케이션 계층에서해야한다. SQL 데이터베이스는 고도로 구조화되어있어 임의의 데이터를 잘 처리하지 못합니다. – PlexQ

+0

MySQL 5.1 및 이전 버전의 일부 버전에서는 명시 적 내부 조인이 좋지 않다는 점을 언급하면서 주목할 가치가 있습니다. 양방향 조인에서는 관계가 없지만 테이블을 추가하면 경험이 저하 될 수 있습니다. SQL Server는 명시 적 조인 순서를 무시하지만 대부분의 다른 데이터베이스 엔진에서는 그렇지 않습니다. 쿼리 최적화 프로그램은 사용자가 잘 알고 있기 때문에이 작업을 수행하고 있다고 믿을 것입니다. – PlexQ

1

두 가지 : 두 개의 테이블이 다른 분야가있는 경우

SELECT p.* 
    FROM posts AS p 
     INNER JOIN friends f ON p.userid = f.friendid 
    WHERE f.userid = '(Logged In User ID)' 
UNION ALL 
SELECT a.* 
    FROM activity AS a 
     INNER JOIN friends f ON a.userid = f.friendid 
    WHERE f.userid = '(Logged In User ID)' 

는, 다음과 같이로, 2 개 선택 목록을 조정해야합니다 :

절대 명시 적 조인을 사용하지 않으면 명시 적 조인을 사용하지 마십시오. 쿼리의 성능이 저하 될 수 있습니다. 때로는 매우 심각한 경우도 있습니다.

검색어가 올바르게 구성되지 않았습니다. 당신은, 당신은 단지와 F에서 참조를 사용할 수 a와 F에 합류 절에서 전체 페이지를 사용할 수 없습니다 말 :

select p.*, a.* 
    from posts p, activity a inner join friends f on (a.userid = f.friendid)... 
가장 가능성이 당신이 원하는 것을 같은 두 개의 쿼리입니다

:

select a.* from activity a, friends f, users u 
where a.userid = f.friendid 
    and u.userid = f.userid; 
    and u.userid = 'logged in user' 

와 두 테이블이 같은 열이있는 경우, 당신은 노동 조합 같은 것을 사용하여 단일 쿼리를 모두 넣을 수 있습니다

select p.* from posts p, friends f, users u 
where p.userid = f.friendid 
    and u.userid = f.userid 
    and u.userid = 'logged in user' 

:

(select a.* from activity a, friends f, users u 
    where a.userid = f.friendid 
     and u.userid = f.userid 
     and u.userid = 'logged in user' 
) union (select p.* from posts p, friends f, users u 
    where p.userid = f.friendid 
     and u.userid = f.userid 
     and u.userid = 'logged in user') 

같은 열이 없으면 두 선택 결과에 특정 열과 별칭이있는 동일한 열이 있거나 두 개의 쿼리로 돌아 가야합니다.

이 결과 집합에서 정렬해야하는 경우 하위 쿼리가 필요하지만 경고가 있으면 SQL 대신 응용 프로그램 논리에서 정렬 작업이 더 잘 수행되는 것으로 알려져 있습니다. 다른 데이터베이스 엔진은 이와 함께 더 나은 시간을가집니다.여기

+0

"MySQL에서 ** 암시 적으로 ** 조인을 사용하지 마십시오."* –

+0

아니요, 명시 적 의미 : http://en.wikipedia.org/wiki/Join_(SQL) 내가 사용하는 암시 적 조인을 사용하는 대신이 방식으로 INNER JOIN을 지정하면 옵티마이 저가 사용하도록 지시합니다 그것을 우선 주문해라. 그것이 당신에게 복종하든 그렇지 않든간에 또 다른 문제입니다. SQL Server에서는 사용자를 무시하고 사용자보다 더 똑똑하다고 가정합니다. 다른 엔진에서는 그렇지 않습니다. 필자는 MySQL 5.0과 5.1에서 벤치 마크를 수행했는데 암시 적 조인을 사용하는 것이 명시적인 것보다 낫다는 것을 보여줍니다. – PlexQ

+0

죄송합니다. 그러나 이것은 잘못되었습니다. 명시 적 조인은 성능을 저하시키지 않습니다. 그것도 향상되지 않습니다. 그것은 가독성을 향상시킵니다. –

1

몇 가지 문제 : 테이블 별칭을 사용하는의

  1. 유장, 당신은 AS 키워드가 필요하지 않습니다. "게시물 p에서"이면 충분합니다.
  2. 활동 테이블에 대한 제약 조건은 없지만 선택 문의 내용이 다릅니다. 이것은 자연스러운 결합을 할 것이지만 나쁜 Cartesian 제품을 생성 할 것이고 전체 테이블을 반환 할 것입니다. 왜냐하면 당신이 사용자가 필터링하지 않기 때문입니다.

    AND a.userid = p.userid 
    

    또는 다른 조인 절이 추가 :

이 문제가 2 문제를 해결하려면, 당신처럼 어디 클로스에 다른 조건을 추가 할 필요가

INNER JOIN activity a on a.userid = p.userid 
+2

나는 "as"를 피하기 위해 동의하지 않는다 - 가독성을 크게 높이고 디버깅에 도움이된다. "항상"다른 벌거 벗은 단어가 눈에 띄고 버그를 검사 할 수있다. 많은 벌거 벗은 단어가 제자리에서 벗어나 오류의 후보가 될 수 있음). –