给出了以下表格定义:
CREATE TABLE demo (
id integer PRIMARY KEY,
name varchar(10)
);
INSERT INTO demo VALUES (1, 'test');
INSERT INTO demo VALUES (2, 'test');
以下查询(假设它们在语义上相同-如果我错了,请纠正我):
SELECT DISTINCT name
FROM demo
WHERE name = 'test';
SELECT DISTINCT name
FROM demo
WHERE name = 'test'
-- actual value is irrelevant as long
-- as it is > number of entries that would result
LIMIT 10
OFFSET 0;
两者都正确返回:
name
----
test
此外,查询:
SELECT EXISTS(
SELECT DISTINCT name
FROM demo
WHERE name = 'test'
LIMIT 10
OFFSET 0
);
也会正确返回1
(或在PostgreSQL中返回t
)。然而,查询:
SELECT EXISTS(
SELECT DISTINCT name
FROM demo
WHERE name = 'test'
LIMIT 10
OFFSET 1 -- note the offset: 1 more than what the DISTINCTed query should return
);
- Also*在SQLite和MySQL中返回
1
,但在PostgreSQL中返回f
。在PostgreSQL中,似乎将OFFSET
应用于查询结果(不出所料),但在SQLite和MySQL中,DISTINCT
具有优先权。
AFAIK,SQL标准定义了最后要评估的LIMIT/OFFSET
(尽管我自己实际上找不到标准的链接来验证这一点,尽管每次搜索都得到相同的结果...),这意味着PostgreSQL的行为是正确的。
这是一个已在PostgreSQL中修复的错误吗?
测试对象:
- SQLite 3.36.0
- MySQL 8.0.28-0ubuntu0.20.04.3
- x86_64-PC-LINUX-GNU上的PostgreSQL14.2(Debian14.2-1.pgdg110+1),GCC(Debian 10.2.1-6)10.2.1 20210110,64位
有趣的是,使用GROUP BY
而不是DISTINCT
如下所示:
SELECT EXISTS(
SELECT name
FROM demo
WHERE name = 'test'
GROUP BY name
LIMIT 10
OFFSET 1
);
在SQLite上正确返回0
,但在MySQL上仍返回错误的结果1
。
1条答案
按热度按时间fhg3lkii1#
似乎,正如评论中所指出的,这只是MySQL和SQLite中的一个错误。我正要在他们的追踪器上报告这件事,但甲骨文想要大量的信息才能做到这一点,所以我忍住了。
PostgreSQL中的行为是预期的并且是正确的。