2012-05-09 10 views
5

Sto attraversando il dolore di normalizzare un database legacy orribile e ho scoperto quello che penso sia un bug con il DBMS.Se un ORDER BY influisce sul numero di righe restituite una query SELECT?

Questa query restituisce i risultati come mi aspetto:

SELECT DISTINCT RIGHT(SQUEEZE(thing_id), 2) AS thing_id, TRIM(thing_name) 
FROM thing 
ORDER BY thing_id, thing_name; 
(16 rows) 

La prima volta che ho eseguito la query, che aveva inavvertitamente usato le colonne sbagliate nella ORDER BY, come di seguito:

SELECT DISTINCT RIGHT(SQUEEZE(thing_id), 2) AS thing_id, TRIM(thing_name) 
FROM thing 
ORDER BY thing_name, location; 
(33 rows) 

Si noti che l'unica cosa da modificare è ORDER BY e il numero di righe restituite aumenta da 16 a 33. I risultati che fornisce non sono DISTINTUALI come specifica la query.

Credo che questo sia un vero bug, ma un collega dice che è normale perché quando ordiniamo per "posizione", viene selezionato un incluso invisibilmente nei risultati.

L'ORDER BY influisce sul numero di righe restituite in una query SELECT?

EDIT: Ho chiesto a un'altra persona di esaminare le query E ho copiato le query in due file separati, quindi ho eseguito un comando diff su di essi. È sicuro al 100% che l'unica differenza tra le due query sia le colonne elencate in ORDER BY.

AGGIORNAMENTO: Ingres dalla patch di rilascio 14301 con bugfix: "La query Bug 126640 (GENERIC) con espressione order-by e aggregato distinto restituisce più righe del previsto. Le colonne nell'espressione order-by non si trovano nell'elenco di selezione ".

Ad esempio, la query in questione causerà un errore poiché i risultati non sono corretti.

+0

Quale db è? –

+4

Tag dice ingres – ilanco

+0

Puoi mostrare la query esatta? –

risposta

3

Dal momento che l'ordine delle operazioni in SQL è:

FROM > WHERE > GROUP BY > HAVING > SELECT > ORDER BY 

questo non sembra essere un bug davvero. Quale DBMS è?

+0

Come dice il tag, il DBMS è Ingres. –

+1

Grazie a @ Mario, ho scelto la tua risposta perché hai anche specificato _why_ l'ordine BY non dovrebbe influenzare il risultato in questo modo. –

+0

@rusty_turkey grazie. Vorrei anche dire che le sole due clausole in cui le righe possono essere rimosse dal risultato sono 'where' e' having', e forse anche' select' se si specifica "distinto" o se le restanti colonne hanno NULL filari. – MarioDS

3

No, order by deve non influenzare il numero di righe restituite.

Se quello che stai dicendo è vero, sarebbe un bug molto strano e fondamentale. Vorrei triplicare (quindi quadruplicare) le colonne di ritorno su entrambe le query per rendere assolutamente sicuro che questo non sia un semplice errore utente prima di inviare email ai ragazzi di Ingres.

Modifica

In realtà, vorrei anche provare a eseguire le query su un database di backup. Se non disponi di un backup disponibile, potresti essere in grado di cavartela copiando il database che hai (se Ingres lo supporta).

Ho avuto query di restituire risultati senza senso su macchine con hardware difettoso prima. Questo sarà sicuramente qualcosa che vorrete controllare.

+0

I milionesimi controllarono le query perché pensavo che fossi pazzo o non avessi nulla di nuovo su SQL.Come per la modifica del mio post originale, ho anche copiato e incollato le query in due file, quindi ho fatto un diff unix su di loro per confermare. –

+0

@rusty_turkey Vedi la mia modifica –

6

Il problema che vedo è che la seconda query ha una colonna (location) nello ORDER BY che non è inclusa nell'elenco SELECT DISTINCT. In realtà entrambe le query non sono valide SQL (nonostante che Ingres sembra consentirle).Li ho semplificato (in modo che il primo è ok) a:

Query uno (SQL valido):

SELECT DISTINCT 
     thing_id 
    , thing_name 
FROM thing 
ORDER BY thing_id 
     , thing_name ; 

Query due (SQL non valido, dovrebbe produrre errore):

SELECT DISTINCT 
     thing_id 
    , thing_name 
FROM thing 
ORDER BY thing_name 
     , location; 

Perché dovrebbe dà errore? Perché il ORDER BY deve essere elaborato dopo SELECT e DISTINCT. Pertanto, due o più righe nella tabella originale potrebbero avere lo stesso thing_id e thing_name ma diverso location. Queste righe verranno compresse in una sola. Quindi, non esiste un valore di posizione da utilizzare per l'ordine. Anche se c'era (un valiue di posizione nascosta) tenuto, quale sarebbe uno dei tanti?

SELECT DISTINCT query possono essere riscritti con SELECT ALL e GROUP BY (anche non valida in questo caso):

SELECT ALL 
     thing_id 
    , thing_name 
FROM thing 
GROUP BY thing_id 
     , thing_name 
ORDER BY thing_name 
     , location; 

È possibile che questo (query 2) Se effettivamente produrre errori in PostgreSQL, SQL-Server e Oracle. Testare in SQL-Fiddle


Dal numero errato di righe restituite dalla seconda query in Ingres, immagino che ciò che accade dietro le quinte è che lui location segretamente conservato nella lista SELECT in modo che possa essere utilizzato per il ORDER BY e quindi rimosso. Questo, in combinazione con i risultati DISTINCT nel comportamento buggy non standard:

SELECT DISTINCT 
     thing_id 
    , thing_name 
    (, location   --- hidden column) 
FROM thing 
ORDER BY thing_name 
     , location; 

si può chiamare sia un bug o una funzione, non importa, purché si sa che non dovrebbe davvero essere permesso in primo luogo.

Sembra che un problema simile sia stato segnalato un anno fa nel forum Actian: Problem with DISTINCT + ORDER BY e apparentemente risolto. Non ha idea di quale versione si stia riferendo o se sia stato effettivamente corretto o meno (e cosa significa "correzione").


Se si desidera che la query sia valida e si comportano come ci si aspetta, si potrebbe usare somethign come questo:

SELECT 
     RIGHT(SQUEEZE(thing_id), 2) AS squeezed_thing_id 
    , TRIM(thing_name)    AS trimmed_thing_name 
    , MIN(location)    AS a_location   --- or MAX() 
FROM 
    thing 
GROUP BY 
     RIGHT(SQUEEZE(thing_id), 2) 
    , TRIM(thing_name)  
ORDER BY 
     trimmed_thing_name 
    , a_location ;     
+1

Ho fatto ricorso all'apertura di un libro di testo, e dice che l'ORDER BY può specificare colonne che non compaiono nel risultato, ma alcuni dialetti insistono sul fatto che ORDER BY può fare riferimento solo alle colonne che appaiono nel risultato. Quindi in questo caso Ingres lo consente e i server DBMS che hai citato non lo fanno. –

+0

In una query senza 'SELECT DISTINCT' e senza' GROUP BY', sì, penso che quasi tutti (se non tutti) i DBMS permettono a qualsiasi colonna di essere in 'ORDER BY'. Quando c'è un raggruppamento, è molto diverso. E 'SELECT DISTINCT' è una forma di raggruppamento. –

0

Se si aggiunge location alla prima interrogazione, poi entrambi saranno restituire la stessa numero di righe. Il motivo per cui la seconda query restituisce più righe è perché in quella query non si seleziona location. Come affermato in precedenza, alcuni RDBMS non lo consentono, fa Ingres. Probabilmente perché lo standard SQL non lo proibisce?.

Problemi correlati