英文:
MySQL subquery strange issue
问题
MySQL: 5.7.16
有两个表:
rule_conf
表:
CREATE TABLE `rule_conf` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`app_id` bigint(20) UNSIGNED NOT NULL,
`app_log_id` bigint(20) UNSIGNED NOT NULL,
`r_type` tinyint(2) UNSIGNED NOT NULL,
`r_status` tinyint(2) UNSIGNED NOT NULL DEFAULT 0,
...
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_app_log_id`(`app_log_id`) USING BTREE,
INDEX `idx_app_id`(`app_id`) USING BTREE
) ENGINE = InnoDB
app_log_conf
表:
CREATE TABLE `app_log_conf` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`app_id` bigint(20) UNSIGNED NOT NULL DEFAULT 0,
...
INDEX `idx_app_id`(`app_id`) USING BTREE
) ENGINE = InnoDB
有一个 SQL 查询语句:
select app_id from rule_conf
where app_log_id = (
select max(id) from app_log_conf where app_id = 123 and r_status = 1 and r_type = 1
)
这个 SQL 返回一个空结果,没有抛出错误,为什么?
按照我的预期,这个 SQL 应该会抛出一个 Unknown Column
的异常,但实际上没有。
当我在子查询中添加了一个条件 aaa = 1
后,然后执行整个 SQL,我得到了一个错误:1054 - Unknown column 'aaa' in 'where clause
,这是我预期的,因为表 app_log_conf
确实没有包含列 aaa
。
而当我单独执行子查询时,我得到了一个错误:1054 - Unknown column 'r_status' in 'where clause
,这也是我的预期。
有可能是因为主查询中的表 rule_conf
包括了这些列吗?
所以,有人遇到过这样的问题吗?或者有人能解释一下为什么会这样吗?
英文:
MySQL: 5.7.16
There are two tables:
rule_conf
table:
CREATE TABLE `rule_conf` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`app_id` bigint(20) UNSIGNED NOT NULL,
`app_log_id` bigint(20) UNSIGNED NOT NULL,
`r_type` tinyint(2) UNSIGNED NOT NULL,
`r_status` tinyint(2) UNSIGNED NOT NULL DEFAULT 0,
...
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_app_log_id`(`app_log_id`) USING BTREE,
INDEX `idx_app_id`(`app_id`) USING BTREE
) ENGINE = InnoDB
app_log_conf
table:
CREATE TABLE `app_log_conf` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`app_id` bigint(20) UNSIGNED NOT NULL DEFAULT 0,
...
INDEX `idx_app_id`(`app_id`) USING BTREE
) ENGINE = InnoDB
There is a SQL:
select app_id from rule_conf
where app_log_id = (
select max(id) from app_log_conf where app_id = 123 and r_status = 1 and r_type = 1
)
this SQL return an empty result, not throw an error, WHY?
In my expectation, this SQL should throw an exception like Unknown Column
, but it did not.
When I add a condition in subquery aaa = 1
, then executing the holistic SQL, I got an Error: 1054 - Unknown column 'aaa' in 'where clause
, that's my expectation, because table app_log_conf
indeed not including column aaa
.
And when I executing the subquery separately, I got an Error: 1054 - Unknown column 'r_status' in 'where clause
, that's also my expectation.
Is there any possibility because the table 'rule_conf' in main query including those columns?
So, anyone encountered such issue, or can someone explain WHY?
can someone explain why
答案1
得分: 3
子查询知道主查询的列。如果在主查询表和子查询表中有相同的列名,并且您没有在子查询中指定要使用哪一个,那么子查询表的列将优先于主查询表的列。因此,您的查询可以翻译为:
select rule_conf.app_id
from rule_conf
where rule_conf.app_log_id =
(
select max(app_log_conf.id)
from app_log_conf
where app_log_conf.app_id = 123
and rule_conf.r_status = 1
and rule_conf.r_type = 1
);
当涉及多个表时,您应该在所有列名前加上它们所属的表,以避免错误。使用别名可以帮助解决这个问题。
子查询知道主查询的列有时是必要的,特别是当我们想要编写一个相关子查询时,例如:
select rc.app_id
from rule_conf rc
where rc.app_log_id =
(
select max(alc.id)
from app_log_conf alc
where alc.app_id = rc.app_id
);
英文:
The subquery knows the columns of the main query. If there is the same column name in your main query table and your subquery table and you don't qualify which you want in the subquery, the subquery table's column has precedence over the main query table's one. Your query hence translates to:
select rule_conf.app_id
from rule_conf
where rule_conf.app_log_id =
(
select max(app_log_conf.id)
from app_log_conf
where app_log_conf.app_id = 123
and rule_conf.r_status = 1
and rule_conf.r_type = 1
);
When working with more than one table, you should qualify all column names with their table in order to avoid mistakes. Using alias table names helps with this.
That the subquery knows the columns of the main query is necessary sometimes, when we want to write a correlated subquery, e.g.
select rc.app_id
from rule_conf rc
where rc.app_log_id =
(
select max(alc.id)
from app_log_conf alc
where alc.app_id = rc.app_id
);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论