2014-05-21 2 views
0

특정 도구로 해결할 수있는 퍼즐 목록이 있다고 가정합니다. 이제는 도구를 선택하고 해결할 수있는 퍼즐과 목록에있는 도구를 알고 싶습니다. 여기에 (MySQL 용) 내 SQL 내가 Puzzle1, 도구 1, 2 Puzzle1, TOOL2, 2 Puzzle2, 도구 1, 1 Puzzle3, Tool3 같은 것을 얻을 결과하위 항목으로 쿼리 제한

SELECT p.name puzzle, countr.cnt, tool.id toolId,[etc] 
FROM 
puzzles p 
INNER JOIN 
tools_for_puzzle tfp 
ON tfp.id_puzzle = p.id 
INNER JOIN 
tools t 
ON t.id= tfp.id_tool 
INNER JOIN 
(
    select tfp2.id_puzzle, count(*) cnt from tools_for puzzle tfp2 
    where tfp2.id_tool in (21,22,23,24,25,26,27) group by id_puzzle 
) countr 
ON 
countr.id_puzzle=tfp.id_puzzle 
WHERE 
t.id IN (21,22,23,24,25,26,27) 
    order by cnt desc limit 50 

, 1

이 카운터는 더 많은 도구가 있기 때문에 어느 퍼즐을 쉽게 풀 수 있는지 알고 있어야합니다. 그래도 쿼리가 충분히 최적화되었는지는 잘 모르겠다. 내가 얻은 결과는 50 개의 가능한 퍼즐을 나타내지 않는 50 개의 행이지만 행의 합입니다. 내가 필요로하는 50 가지 도구의 ID를 사용하면 실수로 한 가지 퍼즐 만 얻을 수 있습니다.

퍼즐, 도구 대신 50 가지 퍼즐을 얻으려면 어떻게 쿼리를 설정합니까? 퍼즐로 그룹화하면 도구의 ID/이름이 손실됩니다! 세 번째 쿼리를 실행해야합니까?

답변

2

내가 이해한다면 주어진 도구 세트와 일치하는 퍼즐을 찾고 있습니다. 이것은 "set-within-sets"하위 쿼리의 예입니다. 이를 해결하는 유연한 방법은 집계를 사용하는 것입니다.

다음 쿼리는 각 퍼즐에 대해 도구 수와 쉼표로 구분 된 목록을 반환합니다. 대부분의 도구에서 목록과 일치하는 퍼즐을 가장 적게 주문합니다 :

SELECT p.name, p.puzzle, count(*) as numtools, group_concat(t.id) as tools 
FROM puzzles p INNER JOIN 
    tools_for_puzzle tfp 
    ON tfp.id_puzzle = p.id INNER JOIN 
    tools t 
    ON t.id= tfp.id_tool 
WHERE t.id IN (21,22,23,24,25,26,27) 
GROUP BY p.id 
ORDER BY numtools desc; 
+0

나는 group_concat을 몰랐습니다! 그것은 내 문제를 해결하고 쿼리를 더 빠르게 만들었습니다! 흥미로운 점은 다른 방법이 있다는 것입니다. 이 도구가 필요한만큼 가장 우아한 것 같습니다. 감사! – maugch

+0

이것은 바보 같지만 noSQL 쿼리로 변경할 수 있습니까? 쿼리를 테스트 중이므로 속도가 느려지므로 기술을 변경하면 속도가 변경 될 수 있는지 궁금합니다. – maugch

+0

@mobinoob. . . 이를 NoSQL 태그를 사용하여 별도의 질문으로 요청해야합니다. –

관련 문제