PDA

View Full Version : ORDER BY in SQL


pjtaddei
17-02-2002, 20:15
ciao, ho questo piccolo dilemma:

devo ordinare i campi scaricati dal database utilizzando come parametro non una colonna ma un parametro calcolato con i valori trovati via via:

cioè se la tabella ha come colonne A - B -C io voglio ordinare i valori in ordine crescente di A*B/D

come devo fare?
su uno schifosissimo libro della microsoft ho letto che l'order by prevede solo il nome di una colonna! possibile? io di quelli non mi fido!!! ma di voi si :)

ilsensine
18-02-2002, 07:47
Non so se funziona, ma prova con:
select A, B, C, (A*B/D) as espressione ... order by espressione

pjtaddei
18-02-2002, 12:42
Bravissimo!!!!! ti sei meritato una birra virtuale :)

e visto che ci siamo...

per evitare la divisione per zero uso l'espressione A/(B+1) ma in alcuni casi l'ordinamento non è perfetto per tutti i valori,

cme faccio a fargli fare la divisione solo quando B != 0 e altrimenti assegnare il valore 0????

se rispondi le birre diventano 3!

Mirkuz
18-02-2002, 12:58
select A, B, C,
case when C = 0
Then 0
Else (A*B/C)
End espressione, ... order by espressione


Ciaoooo

pjtaddei
18-02-2002, 17:48
no, deve esserci qualcosa che non va!
sto aggredendo l'sql da qualche settimana ma mi pare che ci sia qualcosa che non quadri:

non dovrei comunque utilizzare il comando "AS espressione" da passare poi in "ORDER BY espressione"?

e se utilizzo "END espressione" sql come fa a capire dove l'ho aperta?

cionci
18-02-2002, 19:22
Originariamente inviato da Mirkuz
[B]select A, B, C,
case when C = 0
Then 0
Else (A*B/C)
End espressione, ... order by espressione

Questo comunque non credo che sia SQL standard...o sbaglio ?

SELECT [a], [b], [c]
FROM tabella1
ORDER BY ([a]*[b]);

In Access quella sopra funziona...non ho provato con altri DBMS...

pjtaddei
18-02-2002, 22:03
in SQL non posso dare direttamente un espressione come campo di ORDER BY,

ma la soluzione postata da il sensine funziona perfettamente,
quello che mi serve ora è poter inserire nella creazione dell'espressione un if!!!!

cionci
19-02-2002, 08:19
Stai parlando di SQL Server...almeno specifica ;)

lufo
19-02-2002, 08:43
e se provi così??

select A, B, C,
case when C = 0
Then 0 AS Espressione
Else (A*B/C) AS Espressione
Order by espressione

Mirkuz
19-02-2002, 10:46
L'espressione che avevo scritto l'altra volta non mi risulta essere sbagliata.
L'ho provata col query analizer e funge perfettamente.
Sul server ho SQL server 7, quindi direi una versione standard, a meno che non mi sfugga qualcosa.
la sintassi per fare una specie di IF THEN ELSE estraendo dei dati da un DB è quella del CASE WHEN.

SELECT A, B, CASE WHEN C=0 THEN 0 ELSE (A*B/C) END Espressione, D, E, F,..... FROM Tabella

Ciao

pjtaddei
19-02-2002, 12:25
...non va!!! forse è perchè sul mio computer ho installato MySQL 3... misteri dell'informatica!!

cionci
19-02-2002, 12:40
Originariamente inviato da pjtaddei
[B]...non va!!! forse è perchè sul mio computer ho installato MySQL 3... misteri dell'informatica!!
Almeno dillo cosa hai installato ;)

L'SQL non è un linguaggio standard...o meglio c'è uno standard ANSI, ma ogni DBMS ci fa le sue modifiche proprietarie...
Addirittura MySQL non supporta nemmeno le query annidate...ma in compenso è il più veloce di tutti...

Mirkuz
19-02-2002, 13:10
Non so in MySQL, ma se vuoi provare a fare degli IF la sintassi è:

IF (Condizione)
BEGIN

...OPERAZIONI...

END

Strano che comunque in MySQL non esista un costrutto simile al CASE WHEN...Io fossi in te cercherei su qualche sito specializzato in questo linguaggio.

Grem
20-02-2002, 13:58
Semplice, basta modificare un po' lo statement postato da ilsensine:

"select A, B, C, (A*B/D) as espressione
where D is not null
order by espressione"

Prova un po' così, dai...

Mirkuz
20-02-2002, 14:48
Ho trovato una funzione di MySQL che restituisce NULL se i due parametri che gli passi sono uguali, mentre restituisce il primo parametro se sono diversi...E se provassi a usarla così?

set @var= 0
select NULLIF(a*b/c,a*b/@var) as Espressione

In pratica, se l'espressione ha uno zero a denominatore, Espressione vale NULL (tu volevi lo zero, ma forse ti va bene lo stesso), altrimenti vale il risultato di a*b/c

se ne vuoi sapere di più prova sul sito www.mysql.com

fammi sapere!

soalle
20-02-2002, 14:48
correggerei con:

where C<>0

poiché 0 non significa NULL

ed eventualmente fai una union con le tuple in cui C=0 mettendo un valore di default nella colonna (A*B/C) (le union MySQL le fa almeno ???)
In questo modo però l'ordinamento avviene solo sul primo gruppo di tuple.
Se posso esserti ancora utile chiedi pure...

Abbiamo risposto in contemporanea... mi riferivo al messaggio di grem

Mirkuz
20-02-2002, 14:52
Quest'altra forma forse fa ancora più il caso tuo...


select a, b, c, IF(c = 0,0,a*b/c) as Espressione from...


se la condizione c= 0 è verificata restituisce 0, altrimenti a*b/c.

Arifammi sapere.

soalle
20-02-2002, 14:54
Non voglio essere polemico ma io preferisco lo standard ANSI SQL-92 piuttosto che costrutti specifici del DBMS

Mirkuz
20-02-2002, 15:00
Ma se non funziona neanche il CASE WHEN non è mica colpa mia...

Con la soluzione di Grem, che è comunque ottima, ti perdi un sacco di dati per strada. Infatti se c = 0 non estrae nulla, mentre mi pareva di aver capito che si volesse estrarre 0 come valore dell'espressione, senza perdermi l'estrazione di tutti gli altri campi (a,b, etc...)

soalle
20-02-2002, 15:05
infatti se leggi sopra consiglio di fare la union con i valori in cui C=0 ed il relativo valore di default che si vuole assegnare alla colonna (A*B/C). Altra piccola modifica se si preferisce che queste tuple vengano visualizzate all'inizio si selezionano prima quelle C=0 e successivamente si fa la union con quelle C<>0.
Ciaociao Soalle

Mirkuz
20-02-2002, 15:10
Non avevo letto la tua risposta di prima.
In effetti mySQL supporta le UNION e quindi non dovrebbe dare problemi

soalle
20-02-2002, 15:14
;)

Grem
20-02-2002, 18:03
Originariamente inviato da soalle
[B]correggerei con:

where C<>0

poiché 0 non significa NULL

Hai perfettamente ragione, ho cannato il costrutto.
Avrei dovuto scrivere quello che hai scritto tu, infatti...
:)

pjtaddei
20-02-2002, 19:26
intanto ringrazio tutti per la partecipazione:
mi sa che mi conviene organizzare una cena virtuale! :) :/

comunque non riesco a fargli pappare il comando ...

cioè

SELECT A, B/C AS ratio WHERE C <> 0 FROM tabella ORDER BY C
DESC

mi da errore!!!!!!!!

PS: nel caso riuscissi a farlo andare la union dovrebbe essere fatta come:
SELECT A, B/C AS X WHERE C <> 0
UNION
SELECT A, 0 AS X WHERE C = 0
FROM tabella ORDER BY X DESC
giusto?

cionci
20-02-2002, 19:29
No, così :

SELECT A, B/C AS X FROM tabella
WHERE C <> 0
ORDER BY X DESC
UNION
SELECT A, 0 AS X FROM tabella
WHERE C = 0
ORDER BY X DESC

soalle
20-02-2002, 19:33
Per quanto riguarda l'errore sarebbe interessante vedere il tipo di errore che ti dà, se lo puoi postare....
Ciao soalle
PS: C è definito nella tabella come integer o decimal giusto?

pjtaddei
20-02-2002, 19:37
auuuuuuuuu
che pirlone!!!!!!!!

il WHERE va dopo FROM tabella!!!!!!!!!

SELECT A, B/C AS X FROM tabella WHERE C <> 0 ORDER BY X DESC


ora provo a correggere l'union

grazie per la tempestività

cionci
20-02-2002, 19:39
Ad esempio, sotto Access non funziona...
Dice che vuole nel "Order By" un campo selezionato dalla "Select"...

soalle
20-02-2002, 19:40
non essendomene accorto mi associo anch'io tra i pirloni.... ;)

soalle
20-02-2002, 19:42
ma sappiamo che access è limitato ed ha un sql tutto tutto suo (vedi ad esempio il comando top())

cionci
20-02-2002, 19:42
I me ne sono accorto solo dopo...infatti poi ho corretto ;)

cionci
20-02-2002, 19:45
Originariamente inviato da soalle
[B]ma sappiamo che access è limitato ed ha un sql tutto tutto suo (vedi ad esempio il comando top())
Concordo...ma così mi funziona...

SELECT * FROM (SELECT [Aa], [Ba]/[Ca] As [Xa] FROM Tabella1 WHERE [Ca] <> 0)
ORDER BY [Xa]
UNION SELECT [Aa], 0 As [Xa] FROM Tabella1
WHERE [Ca] = 0
ORDER BY [Xa] DESC;

pjtaddei
20-02-2002, 19:46
eheh..

sapete ora che cosa vi dico?

la UNION .... NON VAAAAAAAAAAAA!!!!

ora mi sparo.

soalle
20-02-2002, 19:48
riguardo la soluzione di cionci dovrebbe funzionare, ma non so se funziona su MySQL (che è abbastanza limitato in quanto potenzialità espressive)...la union dovrebbe funzionare
Dicci cosa non va o meglio l'errore che ti dà....

cionci
20-02-2002, 19:49
Su mySql la mia non può andare...perchè ci sono Select annidate...

pjtaddei
20-02-2002, 19:53
la query la inserisco come parametro nella funzione di PHP quindi l'unico errore che ricevo è sempre
Supplied argument is not a valid MySQL result

pjtaddei
20-02-2002, 19:55
dunque sono costretto per forza a fare 2 chiamate successive, giusto?

soalle
20-02-2002, 19:56
l'unico dubbio che mi viene in mente è che in qualche modo la select non accetti direttamente una espressione costante come:

Select a,0
.....

prova a fare girare solo la seconda query (dopo la union) per vedere se funziona da sola...
Tra un po' cmq vi devo lasciare, eventualmente ci si aggiorna domani

soalle
20-02-2002, 19:59
Per quanto riguarda le chiamate successive: potrebbe essere una soluzione certo non elegante ma potresti mettere insieme tu a mano il risultato delle due query separate

soalle
20-02-2002, 20:03
non ho pensato a questo (e poi vado veramente.... ;))!!!!
Per la seconda query se il problema è veramente il fatto che la select non accetta direttamente un valore costante (non me lo ricordo sinceramente) puoi fare:

......
union
Select A,C
FROM Tabella
WHERE C=0

Ciao Soalle

pjtaddei
20-02-2002, 20:05
no, purtroppo l'errore non è li: il 2° select lo esegue correttamente!!!

inizio a pensare che dovrò riscrivere tutta la pagina (sempre che non abbandoni tutto per fuggire in tibet dove di sicuro non hanno di questi problemi)

possibile che non possa utilizzare la UNION? (iniziava a piacermi!!!)

soalle
20-02-2002, 20:09
non vorrei sia una limitazione di my sql... cmq continuo ad essere curioso sulla definizione della tabella, dei campi a,b,c.
ciao soalle

pjtaddei
20-02-2002, 20:10
...comunque per questa sera mi fermo anche io, sono ià abbastanza soddisfatto

grazie a tutti!

..e poi domani mi aspetta lo scritto di Fisica Tecnica

Mirkuz
21-02-2002, 08:59
Non pensavo che il linguaggio SQL potesse appassionare tanto...:)))

Lo so che adesso mi sbranerete, ma perchè non vi va di provare la funzione di mySQL che avevo suggerito?

SELECT IF(C = 0, A*B/C, 0) AS Espressione FROM Tabella

Siccome non ho mySQL sarei curioso di sapere se funge...:)

cia'

pjtaddei
21-02-2002, 20:00
NON E' POSSIBILE:


FUNZIONAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!!!!!!

ma sei un genio!!!
..e io che ti avevo scartato subito!!
complimenti per la sagacia!!!!

Alien
22-02-2002, 05:32
purtroppo arrivo solo ora a leggere, ma, per curiosità, se nella UNION mantieni solo il secondo ORDER BY ed elimini il primo funziona correttamente?

soalle
22-02-2002, 17:49
No: il secondo order by di fatto è superfluo poiché ti ordina il secondo gruppo di tuple su una colonna che è di fatto costante (X è sempre uguale a zero...). Di fatto il primo è necessario per ordinare il primo gruppo di tuple.

Alien
22-02-2002, 22:50
il mio dubbio nasce dal fatto che (almeno in T-Sql) può esistere un unico order by all'interno di una union e deve essere posto alla fine dell'intera query.

Si vede che non è il caso con mySql

soalle
24-02-2002, 13:05
ummmmh.... che cos'è T-SQL, non lo conosco...

Alien
25-02-2002, 10:50
T-Sql = Transact Sql

E' l'Sql usato da Microsoft che differisce in qualche cosa dallo standard Ansi