2015-01-30 2 views
2

나는 다음과 같은 SQL 쿼리를 사용하여 관계형 테이블의 관련 데이터 (게시물을 올린 사용자, 포럼/스레드의 자식 등)와 함께 포럼 게시물을 출력하는 데 사용됩니다. 내가 PDO 위치 자리 표시자를 사용하고JOIN에서 자리 표시자를 사용할 수 있습니까?

(따라서?의) 그래서 내가이 자리 표시자를 사용하고이 쿼리에

SELECT {Lots of select stuff here} 
FROM tab_posts tposts 
INNER JOIN tab_users tuser ON tuser.id=? 
INNER JOIN tab_users tusers ON tposts.user_id=tusers.id 
INNER JOIN tab_ranks tranks ON tusers.rank_id=tranks.id 
INNER JOIN tab_avatars tavatars ON tusers.avatar_id=tavatars.id 
INNER JOIN tab_threads tthreads ON tposts.thread_id=tthreads.id 
INNER JOIN tab_forums tforums ON tthreads.forum_id=tforums.id 
WHERE tposts.thread_id=? AND tforums.rank_id <= tuser.rank_id 

은, 첫 번째는 다른 하나는 세션에서 검색 한 사용자의 ID입니다 요청에서 검색된 스레드 ID (해당 스레드에 속한 게시물 만 나열하도록)

tuser은 세션 사용자이고 tusers은 게시물을 제출 한 사용자의 별칭입니다. 세션 사용자가 해당 게시물을 볼 수 있는지 확인하려면 tuser 만 필요합니다 (액세스 순위에 따라 포럼 테이블의 rank_id이 허용되는 최소 순위 임).

JOIN 섹션의 자리 표시 자 (또는 오히려 모든 변수)가 유효한지 여부를 확인하고 싶습니다. 아니면 테이블을 사용하는 것으로 제한됩니까? 나는 그것을 틀리게 사용하고 있다고 확신한다. 그렇다면 어떻게하면 사용자 순위를 확인할 수 있을까?

내 다른 JOIN이 실제로 유효한지 확실하지 않습니다. bah!

+1

WHERE 구성 요소에'tuser.id =? '를 그냥 추가하지 않는 이유는 무엇입니까? 그렇다면 INNER JOIN에게 과세하는 것을 피할 수 있습니다. – Scopey

+0

자리 표시자는 ** 값 **을 나타내는 모든 것에 사용됩니다. 즉, 네가 두 개의 정수를 전달하기 때문에 사용했던 것처럼 사용할 수 있습니다. 테이블 이름이나 열 이름에는 사용할 수 없습니다. 생각해 보면 자리 표시자가 나타내는 것은 숫자가 모두 끝나고 실행 준비가 끝난 후 문자열입니다. –

+0

조인은 조회 결과를 제한하지 않고 다른 테이블의 열을 선택하기위한 조인입니다. 쿼리의 결과를 더 작은 하위 집합으로 제한하려는 경우 where 절에 속합니다. 선택할 수없는 값에 대해 다른 테이블을 검사해야하는 경우 하위 쿼리를 사용하십시오. –

답변

2

당신은 JOINON 절에 사용하는 자리가 적절한 그렇게 할 수 있습니다 (난 당신이 말할 수없는 경우 가입하여 새로운 해요). ON 조건은 행이 두 테이블 사이에 행을 비교할 때 TRUE로 평가 일부 표현되어야한다, 그래서

FROM 
    t1 
    LEFT JOIN t2 ON t1.id = t2.id AND t2.othercol = ? 

같은 조건은 ON에서 ? 자리의 유효 이용 될 것이다. 위와 같은 결합 조건에서 idothercol 열의 일치가 ? 입력 값과 일치해야 모두 조인을 만족해야합니다. 테이블을 관련시키기 위해 여러 가지 컬럼 일치가 필요하지만 WHERE 조건을 추가하면 LEFT JOINNULL을 생략하고 이로 인해 INNER JOIN처럼 동작 할 때이 사용법은 일반적으로 LEFT JOIN에 나타납니다.

그러나 귀하의 경우에는 요청한 사용자 ID로 결과 집합을 필터링하기 위해 해당 사용자 조건을 WHERE 절로 이동해야합니다.

SELECT {Lots of select stuff here} 
FROM tab_posts tposts 
    INNER JOIN tab_users tusers ON tposts.user_id = tusers.id 
    INNER JOIN tab_ranks tranks ON tusers.rank_id = tranks.id 
    INNER JOIN tab_avatars tavatars ON tusers.avatar_id = tavatars.id 
    INNER JOIN tab_threads tthreads ON tposts.thread_id = tthreads.id 
    INNER JOIN tab_forums tforums ON tthreads.forum_id = tforums.id 
WHERE 
    /* This condition belongs in the WHERE */ 
    tusers.id = ? 
    tposts.thread_id = ? 
    AND tforums.rank_id <= tuser.rank_id 

테이블이 실제로 조인이 표현하는 방식으로 배치되어있는 한 나머지 조인은 올바르게 보입니다.

좀 더 일반화하려면 ? 자리 표시자는 쿼리에서 스칼라 값을 사용하는 모든 위치에서 사용할 수 있습니다. 즉, 문자열 또는 숫자 값 (또는 부울, blob 등)입니다.그래서 당신은 예를 들어, 함수 인수로 사용할 수 있습니다 다음 SELECT 목록에서

/* Truncate a column to some ? number of characters */ 
SELECT LEFT(column, ?) 

또는 스칼라 값을 :

/* Add an additional string suffix to every row in a column */ 
SELECT CONCAT(column, ?) 

당신 테이블 또는 열 이름 대신에 ?을 사용할 수 없습니다, 그래도. 그들은 스칼라 값에 대해서만 작동합니다.

+0

나는 어리 석다. WHERE 절을 왜 나에게 사용하지 않았는 지 모르겠다. 글쎄, 필자가 필요하다면 조인에 사용할 수 있다는 것을 아는 것이 좋다. 설명적인 답변을 주셔서 감사합니다. – Sakuya

+0

@Sakuya 조인을 넘어 이것을 일반화하기 위해'? '사용 사례에 대해 좀 더 추가했습니다. –

관련 문제