【发布时间】:2012-04-16 09:11:46
【问题描述】:
我以简化和扩展的方式重新询问此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:
我现在正试图找出原因。
最终编辑:
所以我已经玩够了 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);
【问题讨论】:
-
只是为了好玩,我将它运行到 SQL,SQL Server 会产生什么,它抱怨
avg2和avg1不存在。我用MAX(T2.score)和MAX(T1.score)替换了它们,它给出了SQLite 结果。当我使用score REAL创建表时,它给出了 MySQL 结果。也许您的 MySQL 架构与 sqlites 不同? -
@ta.speot.is: 你能尝试像
avg(T2.score) as avg2一样添加as(出现两次)吗? -
不起作用。可以肯定的是,在
WHERE、GROUP BY或HAVING中使用别名时,SQL Server 不会掷骰子。 -
在 sqlite 下尝试部分语句我有这个
SQL error: no such function: exists。在 mysql 下工作的关键字可能不在其他数据库系统中。我会亲自使用IN关键字来测试您的子查询的结果 -
似乎 sqlite 团队需要一份错误报告。