2016-08-13 3 views
0

저는 퀴즈 웹 사이트에서 일하고 있습니다. 사용자가 방금 한 퀴즈를 기반으로 사용자가 좋아할 수도있는 퀴즈를 제안해야합니다. 기본적으로 퀴즈에 나온 태그가 있으면 같은 태그로 다른 퀴즈를 풀어야합니다. 그렇지 않으면 같은 범주에서 다른 퀴즈를 당깁니다.여러 테이블 조건을 기반으로 MySQL을 선택하십시오.

내가 원했던 방식은 내가 원하는 방식으로 90 % 작동하지만, 나에게는 매우 부피가 커 보인다. 작동하지 않는 10 %는 활성화 된 퀴즈 만 가져 오는 조건을 추가하는 것을 잊었습니다. WHERE q.active = 1과 같은 것이지만 어디서나 내가 어떻게 그 조건을 추가했는지에 관계없이 계획대로 작동하지 않습니다. 조건이 추가되기 전에받은 빈 세트 나 결과를 얻습니다.

편집 : 내가 처음으로 WHERE 절에 AND q.active = 1를 추가하고 하나의 다른 퀴즈가 동일한 태그로 존재하고 있는지

... @RiggsFolly하여 설명을 읽은 후, 명확히하기 not active 카테고리 선택 문에서 결과를받는 대신 빈 집합을받습니다. 동일한 태그를 가진 퀴즈가없는 경우 태그 선택 명령문이 아닌 카테고리 선택 명령문에 AND q.active = 1을 추가하면 올바른 결과가 반환됩니다.

SELECT 
    IFNULL(q.meta_title, q.title) AS title, 
    IFNULL(url, title) AS url, 
    1 istag 
FROM tag_index t 
LEFT JOIN tag_index ti 
    ON ti.tag_id = t.tag_id 
LEFT JOIN quizzes q 
    ON q.id = ti.quiz_id 
WHERE t.quiz_id = :quiz_id 
    AND ti.quiz_id != t.quiz_id 

UNION ALL 

SELECT 
    IFNULL(q.meta_title, q.title) AS title, 
    IFNULL(url, title) AS url, 
    0 istag 
FROM category_index c 
LEFT JOIN category_index ci 
    ON ci.category_id = c.category_id 
LEFT JOIN quizzes q 
    ON q.id = ci.quiz_id 
WHERE c.quiz_id = :quiz_id 
    AND ci.quiz_id != c.quiz_id 
    AND NOT EXISTS 
     (SELECT 1 FROM tag_index WHERE quiz_id = :quiz_id) 
ORDER BY RAND() LIMIT 1 

도움이나 제안을 보내 주시면 대단히 감사하겠습니다.

+0

더 많은 선, 빈 줄 및 들여 쓰기로이 SQL을 좀 더 아름답게해야합니다. –

+1

그런 다음 where 절에'AND q.active = 1'을 추가하십시오. – RiggsFolly

+0

@ Tiberiu-IonuţStan SQL 문을 매우 아름답게 만드는 것은 분명히 제 강점 중 하나는 아닙니다. 내 글을 좀 더 읽기 쉽게 편집했습니다. 제안 해 주셔서 감사합니다! – Jay

답변

0

당신은 또한 당신의 부속 선택에 active = 1 조건을 추가해야합니다 : 당신이 전혀 그 부속 선택이 필요하지 않습니다 그러나

SELECT 
    IFNULL(q.meta_title, q.title) AS title, 
    IFNULL(url, title) AS url, 
    1 istag 
FROM tag_index t 
LEFT JOIN tag_index ti 
    ON ti.tag_id = t.tag_id 
LEFT JOIN quizzes q 
    ON q.id = ti.quiz_id 
WHERE t.quiz_id = :quiz_id 
    AND ti.quiz_id != t.quiz_id 
    AND q.active = 1 

UNION ALL 

SELECT 
    IFNULL(q.meta_title, q.title) AS title, 
    IFNULL(url, title) AS url, 
    0 istag 
FROM category_index c 
LEFT JOIN category_index ci 
    ON ci.category_id = c.category_id 
LEFT JOIN quizzes q 
    ON q.id = ci.quiz_id 
WHERE c.quiz_id = :quiz_id 
    AND ci.quiz_id != c.quiz_id 
    AND q.active = 1 
    AND NOT EXISTS 
     (SELECT 1 
     FROM tag_index t 
     JOIN tag_index ON ti.tag_id = t.tag_id 
     JOIN quizzes ON q.id = ti.quiz_id 
     WHERE t.quiz_id = :quiz_id 
      AND ti.quiz_id != t.quiz_id 
      AND q.active = 1) 
ORDER BY RAND() LIMIT 1 

할 수 있습니다 첫 번째 istag로 불과 순서 :

SELECT 
    IFNULL(q.meta_title, q.title) AS title, 
    IFNULL(url, title) AS url, 
    1 istag 
FROM tag_index t 
LEFT JOIN tag_index ti 
    ON ti.tag_id = t.tag_id 
LEFT JOIN quizzes q 
    ON q.id = ti.quiz_id 
WHERE t.quiz_id = :quiz_id 
    AND ti.quiz_id != t.quiz_id 
    AND q.active = 1 

UNION ALL 

SELECT 
    IFNULL(q.meta_title, q.title) AS title, 
    IFNULL(url, title) AS url, 
    0 istag 
FROM category_index c 
LEFT JOIN category_index ci 
    ON ci.category_id = c.category_id 
LEFT JOIN quizzes q 
    ON q.id = ci.quiz_id 
WHERE c.quiz_id = :quiz_id 
    AND ci.quiz_id != c.quiz_id 
    AND q.active = 1 
ORDER BY istag DESC, RAND() LIMIT 1 
+0

답장을 보내 주셔서 감사합니다. 불행히도, 같은 태그를 가진 퀴즈가 하나 밖에없고 활성 상태가 아닌 경우에도 여전히 빈 세트를 반환합니다. – Jay

+0

두 번째 조인을 취소했습니다. 당신의 원래 조건은 말하지 않았고 "거기에 존재하지 않습니다 ** 어떤 ** tag for : qiuz_id"로 읽을 수 있습니다. –

0

Easy Solution

제 생각에는 문제의 퀴즈에 tag_id 및 category_id를로드하십시오. 그런 다음 시도하는 것처럼 UNION을 사용하여 간단한 쿼리를 실행하십시오. 그것은 많은 일을 단순화하고 조인의 수를 줄입니다.

는 큰 쿼리 여기

SELECT 
    quiz_pool.quiz_id id, 
    IFNULL(q.meta_title, q.title) AS title, 
    IFNULL(q.url, q.title) AS url 
FROM (

    /* IDs of all quizzes with same tag */ 
    SELECT ti.quiz_id, istag = 1 
    FROM tag_index ti 
    WHERE ti.tag_id IN(SELECT tag_id FROM tag_index WHERE quiz_id = :quiz_id) 
     AND ti.quiz_id <> :quiz_id 
    LIMIT 0, :quiz_count 

    UNION ALL 

    /* IDs of all quizzes with same category */ 
    SELECT ci.quiz_id, istag = 0 
    FROM category_index ci 
    WHERE ci.category_id IN(SELECT category_id FROM category_index WHERE quiz_id = :quiz_id) 
     AND ci.quiz_id <> :quiz_id 
    LIMIT 0, :quiz_count 

) quiz_pool 
INNER JOIN quizzes q ON q.id = quiz_pool.quiz_id AND q.active = 1 
ORDER BY quiz_pool.istag DESC, RAND() 
LIMIT 0, :quiz_count 

으로 모든 작업을 수행하려면 당신은 을 설정할 수 있습니다 quiz_count를 당신이 당신의 논리에 따라 검색 할 퀴즈 수있다. 먼저 동일한 태그로 퀴즈를 찾은 다음 동일한 카테고리에서 퀴즈를하고 퀴즈도 무작위로 추출합니다.

희망이 있습니다.

+0

답장을 보내 주셔서 감사합니다. 이 방법을 사용하면이 방법을 사용하면 조건을 추가하기가 더 쉬워 보이기 때문에이 방법이 효과적 일 것이라고 기대했지만 태그 안에 퀴즈가 없을 때도 여전히 빈 세트를받습니다. – Jay

관련 문제