首页 > 解决方案 > 我不明白为什么这两个带有 WHERE IN 的 SQL 查询会给出不同的结果

问题描述

我想做的是
仅当存在满足 WHERE 条件的数据时才删除行。

表如下所示,我正在使用 MySQL。

table A
+-----------+-------------+---------------------+
|        id | user_id     | created_date        |
+-----------+-------------+---------------------+
|        17 | Amy         | 2021-04-19 17:00:00 |
|        19 | Amy         | 2021-04-20 17:00:00 |
|        20 | Amy         | 2021-04-22 17:00:00 |
|        21 | Bob         | 2021-04-22 17:00:00 |
+-----------+-------------+---------------------+

第一次尝试
我尝试了以下查询,但失败了。
我只想删除 Amy 的 2021-04-20 数据,但它删除了 Amy 的所有三行。

DELETE FROM A
WHERE user_id IN (
  SELECT tmp.user_id from (SELECT user_id FROM A WHERE date(created_date)=date("2021-04-20") AND user_id="Amy") tmp )
AND user_id="Amy";

第二次尝试
成功。
下面的查询只删除满足条件的一行。

DELETE FROM A
WHERE created_date IN (
  SELECT tmp.created_date from (SELECT created_date FROM A WHERE date(created_date)=date("2021-04-20") AND user_id="Amy") tmp )
AND user_id="Amy";

问题

我不明白为什么这两个 SQL 查询会给出不同的结果。
我所做的只是使用另一列。也许我不完全理解IN或子查询:(请提供一些建议。

标签: mysql

解决方案


或许能帮助你理解这种情况的是知道一条 MySQL 语句的执行顺序。

  1. FROM条款
  2. WHERE条款
  3. SELECT条款
  4. GROUP BY条款
  5. HAVING条款
  6. ORDER BY条款

因此,在这种情况下,您的查询解释从您的原始表开始。但是,其 where 条件中的主查询还有另一个查询,该查询也开始按该顺序进行评估。在第一种情况下,子查询的 WHERE 语句中的条件是:

SELECT tmp.user_id from (SELECT user_id FROM example WHERE date(created_date)=date("2021-04-20") AND user_id="Amy") tmp;

该查询的结果是'Amy'. 因为即使您使用 createddate 进行评估,您也在 SELECT 语句中请求 user_id。

在第二种情况下:

SELECT tmp.created_date from (SELECT created_date FROM example WHERE date(created_date)=date("2021-04-20") AND user_id="Amy") tmp

结果是'2021-04-20 17:00:00'在您的搜索中有效地消除一条记录的结果。

WHERE user_id IN继续执行顺序,我们已经注意到,在这两种情况下,数据域都会发生变化,因为您正在使用或更改主查询中的搜索条件WHERE created_date IN

在第一个中,它使用 user_id 查找它找到的所有内容'Amy',在第二个中,它正在使用 date 中查找所有内容'2021-04-20 17:00:00'

仅理论上,如果我们要解决第一种情况,您还应该在主查询中包含日期字段的条件,该字段可以区分“Amy”的 3 种情况。如下所示:

SELECT * FROM example
WHERE user_id IN (
  SELECT tmp.user_id from (SELECT user_id FROM example WHERE date(created_date)=date("2021-04-20") AND user_id="Amy") tmp )
and created_date IN (SELECT tmp.created_date from (SELECT created_date FROM example WHERE date(created_date)=date("2021-04-20") AND user_id="Amy") tmp)

问候。


推荐阅读