2013-05-23 14 views
16

Czy istnieje możliwość zrobienia czegoś takiego?MySQL - Zdefiniuj zmienną w ramach select i użyj jej w ramach tego samego wyboru.

SELECT 
    @z:=SUM(item), 
    2*@z 
FROM 
    TableA; 

Zawsze otrzymuję NULL dla drugiej kolumny. Dziwne jest to, że podczas robienia czegoś podobnego do wszystkiego wszystko działa zgodnie z oczekiwaniami. Czemu?

+1

Bardzo oczekuję, że '@z: = someProcedure (item), 2 * @ z' działające powyżej jest po prostu szczęśliwym zbiegiem okoliczności. – Arjan

Odpowiedz

19

MySQL documentation jest dość jasno:

Jako ogólną zasadę należy nigdy przypisać wartość do zmiennej użytkownika i odczytać wartość w tym samym komunikacie. Możesz uzyskać oczekiwane wyniki , ale nie jest to gwarantowane. Kolejność oceny dla wyrażeń obejmujących zmienne użytkownika jest niezdefiniowana i może zmieniać się w zależności od elementów zawartych w danej instrukcji; ponadto, nie można zagwarantować, że ta kolejność między wersjami serwera MySQL będzie niedostępna dla wersji . W SELECT @a, @a: = @ a + 1, ..., możesz pomyśleć, że MySQL najpierw oceni @a, a następnie wykona zadanie na sekundę . Jednak zmiana instrukcji (na przykład poprzez dodanie klauzuli GROUP BY, HAVING lub ORDER BY) może spowodować, że MySQL wybierze plan wykonania z inną kolejnością oceny.

Możesz robić co chcesz za pomocą podzapytania:

select @z, @z*2 
from (SELECT @z:=sum(item) 
     FROM TableA 
    ) t; 
+3

Zapytanie jest dość skomplikowane, więc nie chcę dodawać żadnych podkwerend. I dlaczego działa z procedurami? Używanie zmiennej w procedurze jest o wiele szybsze niż dwukrotne użycie tej procedury. Więc po prostu tego nie rozumiem, dlaczego to nie powinno działać z sumą (item). – user2370579

+0

Ale podselekcja jest częścią instrukcji select, więc twoja sugestia jest również niezdefiniowana. – philipxy

+0

@philipxy. . . Podzapytanie jest uruchamiane przed zapytaniem zewnętrznym, więc kolejność jest zdefiniowana. –

4

Works w MySQL 5,5

select @code:=sum(2), 2*@code 

+---------------+---------+ 
| @code:=sum(2) | 2*@code | 
+---------------+---------+ 
|    2 |  4 | 
+---------------+---------+ 
+7

Nie, to nie działa w mojej konfiguracji MySQL 5.6; druga kolumna daje 'NULL' przy pierwszej inwokacji, i zwraca 2 razy * poprzedni wynik * jeśli jest uruchamiany ponownie, co może zmylić myślenie, że zadziałało. Teraz interesujące, zarówno kod 'select @ code: = 2, 2 * @ code' oraz' select @code: = rand(), kod 2 * @; '* do * działają w tej samej instalacji (dzisiaj). Tak więc, biorąc pod uwagę dokumentację (patrz odpowiedź Gordona), nie polegałbym na tym, aby zwrócić określony wynik. – Arjan

0
mysql> select @z := sum(5), if(@z := sum(5), 2*@z, 0) ; 
+--------------+------------------------------+ 
| @z := sum(5) | if(@z := sum(5), 2*@z, null) | 
+--------------+------------------------------+ 
|   5 |       10 | 
+--------------+------------------------------+ 

wierzę owijania 2*@z w rachunku if zapewnią sum odbywa się PRZED dodatkowymi obliczeniami.

+2

Jaki jest sens przypisania '@ z', jeśli wykonujesz te same obliczenia w obu miejscach, w których' @ z' jest używany ?! –

Powiązane problemy