在测试一组值时,我总是很容易地使用IN (val1, val2, ...)语法.然而,我想知道它的实际计算结果是什么类型的数据 struct ,这是一个表函数吗?例如:

-- to populate data
CREATE TABLE main_territory (
  name varchar NOT NULL,
  is_fake_territory integer NOT NULL,
  code varchar NOT NULL
);

INSERT INTO main_territory (name, is_fake_territory, code) VALUES ('Afghanistan', 0, 'AF'), ('Albania', 0, 'AL'), ('Algeria', 0, 'DZ');
select '1' as "query#", * from main_territory where code in ('AF', 'AL') union all
select '2' as "query#", * from main_territory where code in (select 'AF' UNION ALL select 'AL') UNION ALL
select '3' as "query#", * from main_territory where code in (select code from main_territory where name ='Albania' or name = 'Afghanistan')

enter image description here

第二个和第三个查询返回一个单列表(这称为标量表吗?),所以我可以想象做(expr1, expr2, ...)次同样的事情——它的计算结果是一个单列表.这是准确的,还是实际的数据类型?

推荐答案

我不会称之为IN ( )谓词元组比较.元组比较(又名行构造函数比较)的一个例子是:

WHERE (col1, col2) = ('abc', 123)

或者甚至可以进行多值行构造函数比较:

WHERE (col1, col2) IN (('abc', 123), ('xyz', 456))

您展示的示例只是IN ( )谓词,它将单个值与一系列值进行比较.如果该值与列表中的任何值匹配,则满足谓词.该列表可以是表达式或文字的固定列表:

WHERE code IN ('AF', 'AL') 

也可以是子查询的结果:

WHERE code IN (SELECT code FROM ...)

如何实现这一点取决于各个RDBMS的代码.它可能必须具体化子查询的结果,并在内部将其存储为列表.在一些软件中,他们可能会使用一个临时表,其中一列作为数据 struct 来存储子查询的结果.然后,IN ( )谓词可以作为对该临时表的连接执行.如果说SQL引擎应该能够高效地完成一件事,那就是连接.:-)

但如果子查询的结果是数百万行,这可能会很昂贵.在这种情况下,一个聪明的优化器将"分解"IN ( )谓词,然后只进行连接.也就是说,它将读取code的每个值,并对第二个表的code列进行索引查找.这意味着没有数据 struct 本身,它只是一个连接的判断.

真正的答案将取决于实施.MySQL和PostgreSQL都是开源的,所以如果您想了解实现,可以try 下载并阅读代码.

Mysql相关问答推荐

客户跨订阅的跨时间线计数

MySQL连接序列

SQL不断返回查询失败,并且不知道从这里到哪里go

我是否需要在 N+1 列上建立索引,才能有效地在 N 列上执行 SELECT,并按其他列排序?

MySQL中的where语句会 destruct 全外连接.

如何让连续 3 周或以上的用户有订单?

如何在 SQL 中计算留存曲线?

从 mysql RDS 导出数据以导入 questDb

MYSQL除以零警告,奇怪的行为

从 2 个不同的表中获取数据并将它们加入 sql

从 SQL 中的左连接和内连接中减go 计数

MySQL过滤食谱上的多对多 - 成分表

按长度过滤 varbinary 字段

MySQL中两个时间字段的分钟差

没有 JDBC 类型的方言映射:1111

我如何决定何时使用右连接/左连接或内连接或者如何确定哪个表在哪一侧?

如何在特定数据库中创建表?

如何使用 SQL 数据库中的经纬度查找最近的位置?

在 Yii2 中执行原始 SQL 查询?

如何将 MySQL 查询结果存储在另一个表中?