MySQL NOT IN表现奇怪

时间:2013-09-12 19:47:00

标签: mysql sql

如果我运行查询:

SELECT *
FROM   mag2
WHERE  environments_env_id LIKE '%test%'
        OR environments_env_id LIKE '%test%'
        OR environments_env_type LIKE '%test%'
        OR environments_host_label LIKE '%test%'
        OR environments_host_type LIKE '%test%'
        OR environments_local_id LIKE '%test%'
        OR samples_date_added LIKE '%test%'
        OR samples_description LIKE '%test%'
        OR samples_exec_arguments LIKE '%test%'
        OR samples_label LIKE '%test%'
        OR samples_owner LIKE '%test%'
        OR samples_sample_id LIKE '%test%'
        OR samples_sample_type LIKE '%test%'
        OR samples_source LIKE '%test%'
        OR task_state_state LIKE '%test%'
        OR task_state_state_id LIKE '%test%'
        OR tasks_env_id LIKE '%test%'
        OR tasks_env_return_code LIKE '%test%'
        OR tasks_env_runtime LIKE '%test%'
        OR tasks_env_start LIKE '%test%'
        OR tasks_exec_arguments LIKE '%test%'
        OR tasks_global_risk_score LIKE '%test%'
        OR tasks_owner_risk_score LIKE '%test%'
        OR tasks_sample_id LIKE '%test%'
        OR tasks_state_id LIKE '%test%'
        OR tasks_task_id LIKE '%test%'
        OR tasks_task_start LIKE '%test%'
        OR event LIKE '%test%' 

我得到249的结果。我想从使用NOT IN的查询中删除100个结果,tasks_task_id是数据库中的唯一索引,并且没有任何重复项。 我在AND NOT IN的声明如下:

SELECT *
FROM   mag2
WHERE  environments_env_id LIKE '%test%'
        OR environments_env_id LIKE '%test%'
        OR environments_env_type LIKE '%test%'
        OR environments_host_label LIKE '%test%'
        OR environments_host_type LIKE '%test%'
        OR environments_local_id LIKE '%test%'
        OR samples_date_added LIKE '%test%'
        OR samples_description LIKE '%test%'
        OR samples_exec_arguments LIKE '%test%'
        OR samples_label LIKE '%test%'
        OR samples_owner LIKE '%test%'
        OR samples_sample_id LIKE '%test%'
        OR samples_sample_type LIKE '%test%'
        OR samples_source LIKE '%test%'
        OR task_state_state LIKE '%test%'
        OR task_state_state_id LIKE '%test%'
        OR tasks_env_id LIKE '%test%'
        OR tasks_env_return_code LIKE '%test%'
        OR tasks_env_runtime LIKE '%test%'
        OR tasks_env_start LIKE '%test%'
        OR tasks_exec_arguments LIKE '%test%'
        OR tasks_global_risk_score LIKE '%test%'
        OR tasks_owner_risk_score LIKE '%test%'
        OR tasks_sample_id LIKE '%test%'
        OR tasks_state_id LIKE '%test%'
        OR tasks_task_id LIKE '%test%'
        OR tasks_task_start LIKE '%test%'
        OR event LIKE '%test%'
           AND `tasks_task_id` NOT IN ( '1762', '1763', '1764', '1765',
                                        '1766', '1779', '1787', '1836',
                                        '1837', '1838', '1839', '1840',
                                        '1841', '1850', '1852', '1856',
                                        '1893', '1914', '1927', '1946',
                                        '1955', '1957', '1969', '1985',
                                        '1986', '2016', '2026', '2038',
                                        '2063', '2098', '2110', '2133',
                                        '2136', '2148', '5056', '5066',
                                        '5068', '5070', '5084', '5106',
                                        '5120', '5132', '5136', '5146',
                                        '5150', '5152', '539', '546',
                                        '547', '548', '549', '550',
                                        '551', '557', '563', '565',
                                        '587', '589', '590', '594',
                                        '602', '603', '621', '622',
                                        '623', '624', '625', '626',
                                        '627', '637', '640', '642',
                                        '643', '645', '646', '648',
                                        '650', '651', '656', '657',
                                        '658', '662', '663', '664',
                                        '665', '671', '672', '675',
                                        '676', '677', '687', '688',
                                        '691', '693', '695', '699',
                                        '701', '702', '756', '762' ) 

结果是150而不是149,我无法弄清楚原因。我也尝试了AND!=并得到了相同的结果。有人可以解释一下原因吗?

3 个答案:

答案 0 :(得分:2)

这可能是一个合乎逻辑的问题。在使用ORAND时要注意,因为MySQL会像这样解释它们:

condition1
OR condition2
OR (condition3
    AND condition4)

所以,尝试用括号将所有OR分组,因为它们都将像“一个条件”和“不在条件”。像这样:

WHERE
(
    condition1
    OR condition2
    OR condition3
)
AND NOT IN (1, 2, 3)

所以你的查询应该是

SELECT *
FROM   mag2
WHERE  
    ( 
          environments_env_id LIKE '%test%'
          OR environments_env_id LIKE '%test%'
          OR environments_env_type LIKE '%test%'
          OR environments_host_label LIKE '%test%'
          OR environments_host_type LIKE '%test%'
          OR environments_local_id LIKE '%test%'
          OR samples_date_added LIKE '%test%'
          OR samples_description LIKE '%test%'
          OR samples_exec_arguments LIKE '%test%'
          OR samples_label LIKE '%test%'
          OR samples_owner LIKE '%test%'
          OR samples_sample_id LIKE '%test%'
          OR samples_sample_type LIKE '%test%'
          OR samples_source LIKE '%test%'
          OR task_state_state LIKE '%test%'
          OR task_state_state_id LIKE '%test%'
          OR tasks_env_id LIKE '%test%'
          OR tasks_env_return_code LIKE '%test%'
          OR tasks_env_runtime LIKE '%test%'
          OR tasks_env_start LIKE '%test%'
          OR tasks_exec_arguments LIKE '%test%'
          OR tasks_global_risk_score LIKE '%test%'
          OR tasks_owner_risk_score LIKE '%test%'
          OR tasks_sample_id LIKE '%test%'
          OR tasks_state_id LIKE '%test%'
          OR tasks_task_id LIKE '%test%'
          OR tasks_task_start LIKE '%test%'
          OR event LIKE '%test%' 
       )
       AND `tasks_task_id` NOT IN ( '1762', '1763', '1764', '1765',
                                    '1766', '1779', '1787', '1836',
                                    '1837', '1838', '1839', '1840',
                                    '1841', '1850', '1852', '1856',
                                    '1893', '1914', '1927', '1946',
                                    '1955', '1957', '1969', '1985',
                                    '1986', '2016', '2026', '2038',
                                    '2063', '2098', '2110', '2133',
                                    '2136', '2148', '5056', '5066',
                                    '5068', '5070', '5084', '5106',
                                    '5120', '5132', '5136', '5146',
                                    '5150', '5152', '539', '546',
                                    '547', '548', '549', '550',
                                    '551', '557', '563', '565',
                                    '587', '589', '590', '594',
                                    '602', '603', '621', '622',
                                    '623', '624', '625', '626',
                                    '627', '637', '640', '642',
                                    '643', '645', '646', '648',
                                    '650', '651', '656', '657',
                                    '658', '662', '663', '664',
                                    '665', '671', '672', '675',
                                    '676', '677', '687', '688',
                                    '691', '693', '695', '699',
                                    '701', '702', '756', '762' ) 

答案 1 :(得分:1)

AND的{​​{3}}高于OR,因此您的查询实际上是:

(..)
    OR tasks_task_start LIKE '%test%'
    OR ( event LIKE '%test%'
       AND `tasks_task_id` NOT IN ( ... ))

将所有OR括在括号中:

SELECT *
FROM   mag2
WHERE ( environments_env_id LIKE '%test%'
        OR environments_env_id LIKE '%test%'
        OR environments_env_type LIKE '%test%'
    (...)
        OR tasks_task_start LIKE '%test%'
        OR event LIKE '%test%' )
           AND `tasks_task_id` NOT IN ( ... ) 

答案 2 :(得分:1)

在组合不同的逻辑比较时,务必确保使用括号。例如,您想使用以下内容:

SELECT * FROM `table1` 
WHERE (var1 LIKE '%foo%' OR var1 LIKE '%bar%' OR ...) 
AND `tasks_task_id` NOT IN ('1762','1763','1764','1765','1766', ... )

operator precedence可能会在这里发挥作用。如果所有大多数task_ids来自'AND'之前的最后一个表,这可能是原因,因为SQL可以将您的查询视为如下:

SELECT * FROM `table1` 
WHERE (var1 LIKE '%foo%' OR var1 LIKE '%bar%' (...) 
OR (
var1 LIKE '%zzz' AND `tasks_task_id` NOT IN ('1762','1763','1764', ... )
) )