MySQL - 在WHERE子句中的NOT IN查询,在第一个表上使用相同的结构但在第二个表上没有

Vol*_*cho 2 mysql sql notin

我想从一个表调整一个简单的MySQL查询到另一个表.第一个查询正在按预期工作,但第二个修改后的查询未显示预期结果,但我无法弄清楚结构中的任何差异.

这个问题与我之前认为已经解决的问题有关:

WHERE条件中的SQL IF ELSE/CASE子句

简要解释一下qhat查询应该做什么:

我想在SQL SELECT中写一个WHERE条件,它应该显示每个ID最多一个结果.但它应该只在LANG是FR或EN时显示结果.如果没有FR可用于ID,则应优先选择FR并且EN应仅显示为替代.所以结果看起来像这样.

这里是工作查询.这是SQL Fiddle LINK

SELECT * FROM `table1`
WHERE ID = 4
AND lang = 'FR'
OR (lang = 'EN' AND ID = 4 NOT IN (SELECT ID FROM table1 WHERE lang = 'FR'))
Run Code Online (Sandbox Code Playgroud)

这是结构相同的查询.这是SQL Fiddle LINK

SELECT * FROM `epf_application_detail`
WHERE application_id = 281656475
AND language_code = 'PL'
OR (language_code = 'EN' AND application_id = 281656475 NOT IN (SELECT application_id FROM `epf_application_detail` WHERE language_code = 'PL'))
Run Code Online (Sandbox Code Playgroud)

如果第二小提琴能够正常工作,它应该显示出来

+--------------+----------------+---------------+-----------+
|  export_date | application_id | language_code |    title  |
+--------------+----------------+---------------+-----------+
|1377594004198 | 281656475      | 'EN'          | 'PAC-MAN' |
+--------------+----------------+---------------+-----------+
Run Code Online (Sandbox Code Playgroud)

我绝对不知道什么是差别,所以任何帮助都是很有意义的

编辑:最适合我的解决方案(因为我需要将它与union all结合起来,每个application_id需要一个结果)

SELECT *
FROM `epf_application_detail`
WHERE application_id = 281656475 AND
      (language_code = 'PL' OR
       (language_code = 'EN' AND
        application_id NOT IN (SELECT application_id
                               FROM `epf_application_detail`
                               WHERE language_code = 'PL' and application_id is not null
                              )
       )
      )
Run Code Online (Sandbox Code Playgroud)

Gor*_*off 5

您的查询失败,因为您正在进行比较并且 not in:

SELECT *
FROM `epf_application_detail`
WHERE (application_id = 281656475 AND language_code = 'PL') OR
      (language_code = 'EN' AND
       application_id = 281656475 NOT IN (SELECT application_id
----------------------------------^
                                          FROM `epf_application_detail` WHERE language_code = 'PL'))
Run Code Online (Sandbox Code Playgroud)

MySQL将进行第一次比较,并将布尔结果转换为整数not in.根据第一个查询的结构,您需要:

SELECT *
FROM `epf_application_detail`
WHERE (application_id = 281656475 AND language_code = 'PL') OR
      (language_code = 'EN' AND
       application_id NOT IN (SELECT application_id
                              FROM `epf_application_detail`
                              WHERE language_code = 'PL' and application_id is not null
                             )
      )
Run Code Online (Sandbox Code Playgroud)

我还补充说application_id is not null,因为NULL可能导致NOT IN失败.

编辑:

根据您的评论,这应该捕获您的逻辑:

SELECT *
FROM `epf_application_detail`
WHERE application_id = 281656475 AND
      (language_code = 'PL' OR
       (language_code = 'EN' AND
        application_id NOT IN (SELECT application_id
                               FROM `epf_application_detail`
                               WHERE language_code = 'PL' and application_id is not null
                              )
       )
      )
Run Code Online (Sandbox Code Playgroud)

如果您只是从详细信息表中查找一行,则以下内容要简单得多:

SELECT *
FROM `epf_application_detail`
WHERE application_id = 281656475 AND
      language_code in ('PL', 'EN')
ORDER BY language_code = 'PL' desc
LIMIT 1;
Run Code Online (Sandbox Code Playgroud)

这使用特定于MySQL的语法.您的问题没有标记MySQL,但确实使用MySQL语法.