2011-09-25 16 views
8

porównaćdlaczego ta kwerenda zwraca wiersz z wartości null

SELECT distinct u_id,timestamp as time 
FROM my_table; 

i

SELECT distinct u_id,max(timestamp) as time 
FROM my_table; 

Kiedy moja tabela ma wiersze na wszystkich (lub jeśli dodam WHERE który pasuje nie wierszy):

Pierwszy z nich zwraca pusty zestaw wyników (który jest tym, czego się spodziewam) , podczas gdy później zwraca pojedynczy wiersz, który ma wartość null jako wartość dla obu jej pól.

Czy ktoś może mi wyjaśnić, dlaczego drugi działa tak jak on?

Odpowiedz

16

dokumentacji MySQL mówi

MAX() zwraca NULL jeśli nie było żadnych pasujących wierszy.

A jeśli nie masz danych, po prostu zwraca obie wartości jako NULL.

Jeśli chcesz drugie zapytanie zwróci pusty resultset też, trzeba odfiltrować NULL wartości na przykład z HAVING, który można wykorzystać z kruszywa funkcji:

SELECT DISTINCT u_id, MAX(timestamp) as time FROM my_table GROUP BY u_id HAVING time IS NOT NULL; 
+2

Jest to technicznie tylko połowa odpowiedzi - druga połowa to brak klauzuli group-by w drugim, podczas gdy funkcje agregujące są mieszane z nieagregatami, dlatego u_id ma wartość 'NULL' – tobyodavies

0

to rzeczywista odpowiedź na to pytanie jest dość skomplikowany do wyjaśnienia, dla mnie w każdym razie :) Nagłówek: SQL nie obsługuje zagregowanych operatorów, jak w modelu relacyjnym, a jedynie obsługuje specjalny przypadek podsumowania. Ponadto, ponieważ SQL ma tylko jedną strukturę danych - tabela - SQL agregujące wywołania operatora (luźno mówiąc) muszą pojawiać się jako część pewnego wyrażenia tabelowego, dlatego też twoja druga tabela zwraca "pusty" pojedynczy wiersz.

Aby uzyskać pełniejsze/lepsze objaśnienie, patrz: SQL and Relational Theory: How to Accurate SQL Code - C. J. Date (2009), rozdział 7.5. Agregowane operatory.