2

私は MySQL5.1 を使用しており、ジョブに関するアクションを記録するテーブルがあります。そのスキーマ定義は次のとおりです。

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句は適していないかもしれません。

4

1 に答える 1

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' ;
于 2012-09-17T10:02:18.780 に答える