mysql - 为什么 SELECT 结果在 mysql 和 sqlite 之间不同?

标签 mysql sql sqlite

我正在重新询问这个 question以简化和扩展的方式。

考虑这些 sql 语句:

create table foo (id INT, score INT);

insert into foo values (106, 4);
insert into foo values (107, 3);
insert into foo values (106, 5);
insert into foo values (107, 5);

select T1.id, avg(T1.score) avg1
from foo T1
group by T1.id
having not exists (
    select T2.id, avg(T2.score) avg2
    from foo T2
    group by T2.id
    having avg2 > avg1);

使用 sqlite,select 语句返回:

id          avg1      
----------  ----------
106         4.5       
107         4.0       

mysql返回:

+------+--------+
| id   | avg1   |
+------+--------+
|  106 | 4.5000 |
+------+--------+

据我所知,mysql的结果是正确的,而sqlite的是不正确的。我尝试使用 sqlite 转换为 real,如下所示,但它仍然返回两条记录:

select T1.id, cast(avg(cast(T1.score as real)) as real) avg1
from foo T1
group by T1.id
having not exists (
    select T2.id, cast(avg(cast(T2.score as real)) as real) avg2
    from foo T2
    group by T2.id
    having avg2 > avg1);

为什么sqlite返回两条记录?

快速更新:

我针对最新的 sqlite 版本 (3.7.11) 运行语句,仍然得到两条记录。

另一个更新:

我已就此问题向 sqlite-users@sqlite.org 发送了一封电子邮件。

我自己,我一直在玩 VDBE,发现了一些有趣的东西。我拆分了每个 not exists 循环的执行轨迹(每个平均组一个)。

为了获得三个平均组,我使用了以下语句:

create table foo (id VARCHAR(1), score INT);

insert into foo values ('c', 1.5);
insert into foo values ('b', 5.0);
insert into foo values ('a', 4.0);
insert into foo values ('a', 5.0);

PRAGMA vdbe_listing = 1;
PRAGMA vdbe_trace=ON;

select avg(score) avg1
from foo
group by id
having not exists (
    select avg(T2.score) avg2
    from foo T2
    group by T2.id
    having avg2 > avg1);

我们清楚地看到,不知何故,r:4.5 变成了 i:5:

enter image description here

我现在想看看为什么会这样。

最终编辑:

所以我已经把 sqlite 源代码玩够了。我现在更了解野兽了,尽管我会让 original developer整理一下,因为他似乎已经在这样做了:

http://www.sqlite.org/src/info/430bb59d79

有趣的是,至少对我来说,似乎较新的版本(有时在我使用的版本之后)支持插入多个记录,如在上述提交中添加的测试用例中所使用的那样:

CREATE TABLE t34(x,y);
INSERT INTO t34 VALUES(106,4), (107,3), (106,5), (107,5);  

最佳答案

我试图弄乱一些查询变体。

似乎 sqlite 在嵌套 HAVING 表达式中使用先前声明的字段时出错。

在您的示例 avg1 下第二个总是等于 5.0

看:

select T1.id, avg(T1.score) avg1
from foo T1
group by T1.id
having not exists (
    SELECT 1 AS col1 GROUP BY col1 HAVING avg1 = 5.0);

这个不返回任何内容,但执行以下查询会返回两条记录:

...
having not exists (
    SELECT 1 AS col1 GROUP BY col1 HAVING avg1 <> 5.0);

我在 sqlite tickets list 上找不到任何类似的错误.

关于mysql - 为什么 SELECT 结果在 mysql 和 sqlite 之间不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10171403/

相关文章:

php - 如何使用 JSON 从 MYSQL 中的 select 插入数据?

mysql - Apache Nutch 2.3 和 MySQL

MySQL "cant create test file", "Failed to set datadir or directory",无法使用初始密码连接

mysql - 为什么 "<> Null"的行为与 “IS NOT NULL” 不同?

java - 插入中的 SQLite 无法识别的 token 异常

sql-server-2008 - 查询返回许多结果时,“nil:NilClass的未定义方法'[]'”

MySQL更新语句

MySQL - 选择具有最大时间戳的唯一列

php - 将 MySQL SELECT 全部分为 7 个结果部分,并在每个部分上运行新查询

mysql - 本地 Geonames 数据库查询