Ponownie pytam o to question w sposób uproszczony i rozszerzony.Dlaczego wyniki SELECT różnią się między mysql i sqlite?
Rozważ te 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);
używasz SQLite powraca select
oświadczenie:
id avg1
---------- ----------
106 4.5
107 4.0
i powraca MySQL:
+------+--------+
| id | avg1 |
+------+--------+
| 106 | 4.5000 |
+------+--------+
O ile mogę powiedzieć, MySQL wyniki są poprawne, a sqlite są niepoprawne. Próbowałem rzucić do real
z SQLite jak poniżej ale zwraca jeszcze dwa rekordy:
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);
Dlaczego powrotne sqlite dwa rekordy?
Szybka zmiana:
Pobiegłem oświadczenie przed najnowszymi sqlite wersji (3.7.11) i jeszcze dostać dwa rekordy.
Kolejna aktualizacja:
Wysłałem e-mail do [email protected] o problemie.
Ja sam bawiłem się VDBE i znalazłem coś interesującego. Podzielam ślad wykonania każdej pętli not exists
(po jednej dla każdej grupy średniej).
Aby mieć trzy grupy AVG, użyłem następujące oświadczenia:
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);
Widzimy wyraźnie, że jakoś co powinno być r:4.5
stała i:5
:
Jestem teraz próbuje aby zobaczyć, dlaczego tak jest.
Ostateczna edycja:
Więc grałem tyle z kodem źródłowym SQLite. Rozumiem bestię teraz znacznie lepiej, chociaż ja niech original developer rozwiązać to jak zdaje się być już robi:
http://www.sqlite.org/src/info/430bb59d79
ciekawe, przynajmniej dla mnie, wydaje się, że nowsze wersje (kilka razy po wersji używam) obsługuje wstawianie wielu rekordów stosowany w przypadku badanej dodanej we wspomnianym popełnić:
CREATE TABLE t34(x,y);
INSERT INTO t34 VALUES(106,4), (107,3), (106,5), (107,5);
tylko dla zabawy to wpadłem do SQL Server, co przyniosłoby SQL i skarżył 'avg2' i' avg1' nie istnieje. Zamieniłem je na 'MAX (T2.score)' i 'MAX (T1.score)' i dało wynik SQLite. Kiedy stworzyłem tabelę z 'score REAL', otrzymałem wynik MySQL. Być może twój schemat MySQL różni się od sqlites? –
@ ta.speot.is: czy możesz spróbować dodać 'as' jak w' avg (T2.score) jako avg2' (dwa wystąpienia)? –
Nie działa. Całkiem pewne, że SQL Server nie gra w kości, jeśli chodzi o używanie aliasów w 'WHERE',' GROUP BY' lub 'HAVING'. –