私はこの質問を単純化して拡張した方法で再質問しています。
次の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
が、それでも2つのレコードが返されます。
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が2つのレコードを返すのはなぜですか?
クイックアップデート:
最新のsqliteバージョン(3.7.11)に対してステートメントを実行しましたが、それでも2つのレコードを取得します。
別の更新:
この問題についてsqlite-users@sqlite.orgにメールを送信しました。
私自身、VDBEで遊んでいて、何か面白いものを見つけました。の各ループの実行トレースを分割しましたnot exists
(平均グループごとに1つ)。
3つの平均グループを作成するために、次のステートメントを使用しました。
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のソースコードで十分に遊んでいます。私は今、獣をはるかによく理解していますが、元の開発者がすでにそれをしているように見えるので、それを整理させます:
http://www.sqlite.org/src/info/430bb59d79
興味深いことに、少なくとも私には、新しいバージョン(私が使用しているバージョンの後の場合もあります)は、前述のコミットで追加されたテストケースで使用される複数のレコードの挿入をサポートしているようです。
CREATE TABLE t34(x,y);
INSERT INTO t34 VALUES(106,4), (107,3), (106,5), (107,5);