2012-09-17 62 views
2

我使用MySQL5.1,我有一個表,我們記錄有關作業的操作。下面是它的模式定義:MySQL:在多個聯盟中的相同字段值

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; 

我需要創建一個請求生成器,用戶可以通過搜索表「AND」和「OR」運營商以及括號。 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子句可能不適用。

回答

0

我覺得這就夠了:

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' 
     ) 
    ) ; 

,或者如果你要具備的條件分開,這樣就可以構建更復雜的查詢更容易:

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