2011-12-08 2 views
24

좋아, 그래서 하나의 임시 테이블에 userID와 taskID가 있습니다. CompletedTasks라고합니다. userID 및 taskID가 포함 된 두 번째 테이블이 있습니다. PlannedTasks라고합니다.mysql "where not in"두 개의 열을 사용합니다.

완료되었지만 계획되지 않은 모든 taskID 목록을 가져와야합니다. 그래서, 어떻게 든 완료된 작업에서 모든 행을 제거해야합니다 어디 두 PlannedTasks.userID != CompletedTasks.userID AND PlannedTasks.taskID != CompletedTasks.taskID.

이 질문이 의미가되기를 바랍니다. 명확하지 않은 경우 알려 주시면 더 자세히 설명하겠습니다.

팁 주셔서 감사합니다!

+0

상태를 나타내는 데 추가 열이 필요하다고 생각합니다. 실제로 두 개의 테이블이 필요하지는 않습니다. – ajreal

+0

@ajreal 좋은 지적입니다. 아마도 내가 제안한 방식으로 스키마를 조정할 것입니다. 팁을 감사드립니다! – PFranchise

+1

나는 한 테이블과 상태 열보다 두 테이블을 선호하는데, 99 %의 시간. 그리고 1 개의 테이블 위에 11 개의 테이블과 10 개의 상태 컬럼이 있습니다. 하나 또는 여러 상태 열 (MysQL)을 검색하는 쿼리를 최적화하는 것은 쉽지 않습니다. –

답변

62
이 (컴팩트 구문)를 사용할 수 있습니다

: (더 복잡하지만, 적절한 인덱스보다 효율적으로해야한다)

SELECT * 
FROM CompletedTasks 
WHERE (userID, taskID) NOT IN 
     (SELECT userID, taskID 
     FROM PlannedTasks 
    ) ; 

또는 NOT EXISTS 버전 :

SELECT c.* 
FROM CompletedTasks AS c 
WHERE NOT EXISTS 
     (SELECT 1 
     FROM PlannedTasks AS p 
     WHERE p.userID = c.userID 
      AND p.taskID = c.taskID 
    ) ; 

물론을 그 대답은 @jmacinnes의 LEFT JOIN/IS NULL 버전입니다. 내 문제가 해결

SELECT * FROM CompletedTasks WHERE (userID, taskID) NOT IN 
     (SELECT userID, taskID FROM PlannedTasks) ;' 

언급 쿼리 아래 공유 ypercubeᵀᴹ 감사합니다 @

+0

굉장! 고맙습니다. 그런 식으로 두 필드에서 Where를 사용할 수 있는지는 몰랐지만 옵션이 될 것이라는 희망이있었습니다. 다시 한번 감사 드리며 좋은 하루 되세요! – PFranchise

+0

테스트 후 NOT EXISTS 버전이 NOT_IN 버전 –

+0

@Ka보다 빠릅니다. 예, 튜플이있는 NOT IN은 NOT EXISTS만큼 최적화되지 않았습니다. 어떤 버전을 테스트 했습니까? 나는 그들이 새로운 5.7 버전에서 최적화 프로그램을 개선했는지 테스트하지 않았다. –

5

이것이 필요한가요?

select ct.* from 
completedTasks ct 
left outer join plannedTasks pt on ct.taskId = pt.TaskId and ct.userId = pt.userId 
where pt.taskId is null 

그러나 나는이 의견에서 우리가 알고있는 것을 생각해 볼 때 상태 열이 두 테이블보다 우수한 스키마처럼 들린다는 점에 동의합니다.

0

.

+0

이것은 주석이어야합니다. 대답은 없습니다. – sniperd

+0

사실, @ypercube 공유 쿼리에 대한 참조로 약간 변경했습니다. 앞으로 돌볼 것입니다. 감사 –

관련 문제