2012-09-17 2 views
2

나는 MySQL5.1을 사용하며 작업 관련 작업을 기록하는 테이블을 가지고 있습니다. 사용자가 괄호뿐만 아니라 연산자를 사용하여 테이블을 검색 "AND"및 "OR"할 수 있도록 내가 요청 빌더를 만들 필요가MySQL : 다중 UNION에서 동일한 필드 값

CREATE TABLE `actions_log` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `action` varchar(45) DEFAULT NOT NULL, 
    `job_id` int(10) unsigned NOT NULL, 
    `candidate_id` int(10) unsigned NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB; 

: 여기에 스키마 정의입니다. SQL 요청은 후보 ID를 리턴해야합니다. 예를 들어, 그들은 "ActionA OR (ActionB AND ActionC)"과 같은 검색을 할 수 있어야합니다.

나는 그것을 달성하기 위해 UNION 절을 사용하고 특정 작업이 제공 될 때이 작업을 수행합니다

SELECT `candidate_id` FROM (
    SELECT `candidate_id` FROM `actions_log` WHERE `job_id` = 1858 AND `action` = 'a' 
    UNION DISTINCT                    
    (                       
     SELECT `candidate_id` FROM (
      SELECT `candidate_id`, COUNT(`candidate_id`) AS `count` FROM (
       SELECT DISTINCT `candidate_id` FROM `actions_log` WHERE `job_id` = 1858 AND `action` = 'b' 
       UNION ALL                       
       SELECT DISTINCT `candidate_id` FROM `actions_log` WHERE `job_id` = 1858 AND `action` = 'c' 
      ) AS level1 
      GROUP BY `candidate_id` 
     ) AS level2 
     WHERE `count` = 2                                
    )                           
) AS candidates; 

사용자는 작업을 지정하지 않고 검색 할 수 있습니다. 이 경우 모든 작업이 일치해야합니다.

문제가있는 곳은 다음과 같습니다. 동일한 작업이 올바른 결과를 가져와야합니다. 예를 들어 위의 예제를 사용하면 작업 1에 "ActionA"를, 작업 2에 "(ActionB AND ActionC)"을 유효한 일치로해서는 안됩니다.

작업을 지정하지 않으면이 작업을 수행 할 수있는 방법을 찾을 수 없습니다. 어쩌면 UNION 절이 그런 경우에가는 길은 아닙니다.

SELECT candidate_id 
FROM actions_log AS a 
WHERE job_id = 1858 
    AND (action = 'a' 
    OR action = 'b' 
    AND EXISTS 
     (SELECT candidate_id 
      FROM actions_log 
      WHERE job_id = a.job_id 
      AND action = 'c' 
     ) 
    ) ; 

또는 당신이 더 복잡한 쿼리를 구축 할 수 있도록 조건을 분리해야 할 경우 쉽게 :

답변

0

나는이 충분하다 생각

SELECT candidate_id 
    FROM actions_log AS a 
    WHERE job_id = 1858 
     AND action = 'a' 
UNION DISTINCT 
    SELECT b.candidate_id 
    FROM actions_log AS b 
     JOIN actions_log AS c 
     ON c.candidate_id = b.candidate_id 
     AND c.job_id = b.job_id 
    WHERE b.job_id = 1858 
     AND b.action = 'b' 
     AND c.action = 'c' ; 
+0

문제는 어떤 작업 ID가없는 경우 지정된. – jmfontaine

+0

작업을 지정하지 않으면'job_id = 1858' 조건을 제거하십시오. –

+0

내 솔루션이 너무 복잡했습니다. 당신은 훨씬 간단하고 일을합니다. 감사! – jmfontaine

관련 문제