MySQL - WHERE 子句中的 NOT IN 查询具有相同的结构,适用于第一个表但不适用于第二个表
Posted
技术标签:
【中文标题】MySQL - WHERE 子句中的 NOT IN 查询具有相同的结构,适用于第一个表但不适用于第二个表【英文标题】:MySQL - NOT IN query in WHERE clause with same structure working on first table but not on second table 【发布时间】:2013-09-06 16:33:50 【问题描述】:我想将一个简单的 mysql 查询从一个表调整到另一个表。第一个查询按预期工作,但第二个修改后的查询未显示预期结果,但我无法弄清楚结构有什么不同。
这个问题与我之前认为已经解决的问题有关:
SQL IF ELSE / CASE clause in WHERE condition
简短地解释了查询应该做什么:
我想在 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'))
这是结构相同的查询。这是 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'))
如果第二个小提琴可以正常工作,它应该会显示
+--------------+----------------+---------------+-----------+
| export_date | application_id | language_code | title |
+--------------+----------------+---------------+-----------+
|1377594004198 | 281656475 | 'EN' | 'PAC-MAN' |
+--------------+----------------+---------------+-----------+
我完全不知道有什么区别,所以非常感谢任何帮助
编辑:最适合我的解决方案(因为我需要将它与 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
)
)
)
【问题讨论】:
AND application_id = 281656475 NOT IN
不等同于第一个查询。相当于AND true/false NOT IN
我在 SQL 方面不是很有经验,老实说,我并不真正理解“AND true/false NOT IN”是什么意思,也不知道如何纠正这个问题。我还更新了 ID = 4 的第一个查询,它也在更新的小提琴中工作
没有特定于 sql 的,如果是其他语言,它更像是if (($x == 281656475) && some_other_function) ...
。
【参考方案1】:
您的查询失败,因为您正在进行比较和 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'))
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
)
)
我还添加了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
)
)
)
如果你只是从明细表中查找一行,下面的就简单多了:
SELECT *
FROM `epf_application_detail`
WHERE application_id = 281656475 AND
language_code in ('PL', 'EN')
ORDER BY language_code = 'PL' desc
LIMIT 1;
这使用 MySQL 特定的语法。您的问题未标记 MySQL,但确实使用了 MySQL 语法。
【讨论】:
在原始表(相当大)上运行查询时,它给了我 868,013 个结果。它显示所有 application_id 的结果它不仅输出一个结果 application_id = 281656475 AND language_code = 'EN' 我认为我的请求可能没有明确提到这一点跨度> @VolkaRacho 。 . .如果你的条件是application_id = 281656475 AND language_code = 'EN'
,那你为什么有OR
子句呢?只需使用where
语句的第一部分。
我需要实现的是:如果 application_id = 281656475 AND language_code = 'PL'
存在则使用 application_id = 281656475 AND language_code = 'PL'
。但在某些情况下,ID 不存在 language_code = 'PL'
(在这种情况下为:application_id = 281656475
)。如果是这种情况,查询应输出此 application_id = 281656475
的值,但从始终存在的 language_code = 'EN'
所在的行输出。我对 SQL 的了解非常有限,这就是为什么我在链接的 *** 问题中询问解决方案的原因。在这里,其他人提出了 OR 的解决方案
太棒了!您的 EDIT 的第一个脚本完全符合我的需要,因为它还使用 union all 并为每个 application_id 显示一个结果。非常感谢!【参考方案2】:
你可以替换
not IN
与
and NOT exists
SELECT * FROM `epf_application_detail`
WHERE application_id = 281656475
AND language_code = 'PL'
OR (language_code = 'EN' AND
application_id = 281656475 and NOT exists (SELECT application_id FROM `epf_application_detail` WHERE language_code = 'PL'))
【讨论】:
以上是关于MySQL - WHERE 子句中的 NOT IN 查询具有相同的结构,适用于第一个表但不适用于第二个表的主要内容,如果未能解决你的问题,请参考以下文章
MySQL UDF 仅适用于 `IF` 中的 `WHERE` 子句