2013-06-10 12 views
6

Here Ho posto la domanda sulla query non funzionante.valore> = tutto (selezionare v2 ...) produce risultati diversi dal valore = (selezionare max (v2) ...)

Accidentalmente (con l'aiuto di una risposta) ho trovato come rendere la soluzione giusta. Il problema è che non capisco perché producono risultati diversi.

Così, il database ha questo schema:

enter image description here

E sto ricerca per tutti i modelli dal PC, Printer e Laptop con il prezzo più alto . Tutte queste tabelle possono avere una colonna non univoca model, poiché gli articoli con diverso code potrebbero avere lo stesso modello.

mia soluzione originale era:

with model_price(model,price) as (
select model,price 
from PC 

union 

select model,price 
from Laptop 

union 

select model,price 
from Printer 
) 

select model 
from model_price 
where price >= all(select price from model_price) 

ha dato risultato sbagliato - il sistema ha restituito * Wrong number of records (less by 2).

La soluzione corretta che funziona è questo:

with model_price(model,price) as (
select model,price 
from PC 

union 

select model,price 
from Laptop 

union 

select model,price 
from Printer 
) 

select model 
from model_price 
where price = (select max(price) from model_price) 

Quindi, perché la soluzione con all produce risultato diverso?


A proposito di motore di SQL: Now we use Microsoft SQL Server 2012 on the rating stages, and MySQL 5.5.11, PostgreSQL 9.0, and Oracle Database 11g on the learn stage in addition. Quindi non so quale motore esattamente usano per asini questo esercizio.

+1

Qualsiasi 'NULL's nei dati? 'seleziona 1 dove 1> = ALL (seleziona unione nulla seleziona 0)' non restituisce righe. –

+0

Siamo spiacenti, non conosco i dati per il secondo database (questo è fatto intenzionalmente per coloro che fanno esercizi non imbrogliano). Non riesco nemmeno a vedere il risultato per le query sul secondo DB, solo riassume ciò che è sbagliato, ad es. '* Numero di record errato (meno di 2)'. – ovgolovin

risposta

5
create table t (f int null); 

select 1 where 1 >= (select max(f) from t); -- 1 
select 1 where 1 >= all(select f from t); -- 2 

insert into t values (null), (0); 

select 1 where 1 >= (select max(f) from t); -- 3 
select 1 where 1 >= all(select f from t); -- 4 

http://www.sqlfiddle.com/#!6/3d1b1/1

Il primo select restituisce nulla, il secondo select rendimenti 1.

MAX restituisce un valore scalare. Se nessuna riga esiste, MAX restituisce NULL. 1 >= NULL non è vero sulla linea 1. D'altra parte, 1 >= all f s è vero, perché non esistono affatto f s per cui la condizione è non true.

Il terzo select restituisce 1, il quarto select non restituisce nulla.

MAX, come tutte le funzioni aggregate, ignora NULL s. MAX(f) è 0 sulla riga 3 e 1 >= 0 è vero. ALL non: valuta 1 >= NULL AND 1 >= 0 sulla riga 4, che non è vero.

+0

Nota che potresti usare 'ISNULL' (alias' ISNULL (price, 0) ') se vuoi usare' ALL' per un altro motivo. – Guvante

+0

Grazie!Questo è probabilmente l'esercizio che dovrei imparare da questo compito! Quindi, 'NULL' non viene promosso a' 0' automaticamente mentre viene confrontato. – ovgolovin

+0

Esatto, e se è possibile che tutti i valori dei campi siano negativi, considerare 'NULL' come' 0' potrebbe anche essere molto sbagliato, quindi è probabilmente una buona cosa che il database non lo faccia automaticamente. Questo può avere senso anche per un campo "prezzo", se hai articoli speciali "sconto". – hvd