2010-07-01 12 views
5

Ho diversi tavoli che vengono uniti per formare una tabella con colonneEsiste una tecnica SQL per ordinare facendo corrispondere più criteri?

designID 
garmentID 
colorID 
sizeID 
imageID 

Ho una funzione che assomiglia a questo [variabili tra parentesi quadre sono opzionali]:

getProductImages($designID, [$garmentID], [$colorID], [$sizeID]); 

lo voglio per restituire tutti imageIDs che corrispondono a $ designID nel seguente ordine:

  • righe che corrispondono a $ garmentID, $ ColorID, e $ sizeID prima
  • righe che corrispondono $ garmentID e $ ColorID prossimi
  • righe che corrispondono ad appena $ garmentID prossimi
  • righe che corrispondono nessuno (solo $ designID) ultimo

ho potuto farlo abbastanza facilmente semplicemente caricando tutto le righe che corrispondono a $ designID e poi le ordinano in PHP, ma la mia comprensione è che generalmente è più veloce fare l'ordinamento in MySQL quando possibile. Ci saranno circa 20 righe corrispondenti a un determinato ID $.

Quindi la mia domanda è duplice: vale la pena fare l'ordinamento in una dichiarazione SQL? Se lo faccio, qual è l'approccio migliore da prendere?

Sarei anche molto interessato a sapere se esiste un nome per questo tipo di ordinamento.

risposta

8

Se ho capito bene, sembra che è possibile utilizzare le espressioni nel vostro ORDER BY, in modo simile alla risposta accettata dato al seguente post Stack Overflow:

Pertanto , la query potrebbe essere simile a questa:

SELECT imageID 
FROM  ... 
JOIN  ... 
WHERE  designID = 100   
ORDER BY garmentID = 1 DESC, 
      colorID = 5 DESC, 
      sizeID = 10 DESC; 

Si noti che garmentID, colorID e sizeID non vengono utilizzati come filtri nella clausola WHERE. I valori vengono utilizzati solo nelle espressioni ORDER BY.

Test case:

CREATE TABLE designs (designID int, garmentID int, colorID int, sizeID int); 

INSERT INTO designs VALUES (100, 1, 1, 1); 
INSERT INTO designs VALUES (100, 1, 2, 2); 
INSERT INTO designs VALUES (100, 1, 5, 3); 
INSERT INTO designs VALUES (100, 1, 5, 10); 
INSERT INTO designs VALUES (100, 1, 5, 15); 
INSERT INTO designs VALUES (100, 1, 8, 20); 
INSERT INTO designs VALUES (100, 2, 5, 10); 
INSERT INTO designs VALUES (100, 2, 6, 15); 
INSERT INTO designs VALUES (101, 1, 1, 1); 
INSERT INTO designs VALUES (101, 2, 1, 1); 

Risultato:

SELECT * 
FROM  designs 
WHERE  designID = 100 
ORDER BY garmentID = 1 DESC, 
      colorID = 5 DESC, 
      sizeID = 10 DESC; 

+----------+-----------+---------+--------+ 
| designID | garmentID | colorID | sizeID | 
+----------+-----------+---------+--------+ 
|  100 |   1 |  5 |  10 | 
|  100 |   1 |  5 |  3 | 
|  100 |   1 |  5 |  15 | 
|  100 |   1 |  1 |  1 | 
|  100 |   1 |  2 |  2 | 
|  100 |   1 |  8 |  20 | 
|  100 |   2 |  5 |  10 | 
|  100 |   2 |  6 |  15 | 
+----------+-----------+---------+--------+ 
8 rows in set (0.02 sec) 

Si noti come la riga che corrisponde al specificato garmentID, colorID e sizeID è prima. In caso contrario, le righe corrispondenti a garmentID e colorID sono successive. Quindi seguono le righe che corrispondono solo a garmentID. Quindi il resto, che corrisponde solo al filtro designID della clausola WHERE.

Credo che valga la pena farlo in SQL. Come @Toby noted in the other answer, in generale non è necessario preoccuparsi delle prestazioni quando si ordina un numero così piccolo di righe, supponendo che si sarà sempre filtrati per designID ... Come per l'altra domanda, non so se c'è un nome per una tale domanda - tendo a chiamarla "ordinare da un'espressione".

+0

Un disclaimer importante su questa tecnica è che le colonne non corrispondenti non verranno ordinate; questo può o non può essere un problema per questo caso d'uso. – Stobor

+0

@Stobor: non credo di aver capito. Puoi fare un esempio? ... Nota anche che penso che l'OP voglia solo una colonna nel set di risultati (una colonna 'imageId'). –

+1

Questo è esattamente quello che stavo cercando, e considerevolmente più elegante di quanto immaginassi sarebbe. – Robert

2

Questo è un problema interessante e leggere la risposta di Daniel mi ha insegnato qualcosa (complicato) che non sapevo di SQL.

Tuttavia,

Se siete sempre e solo probabilità di avere 20 tali disegni, la realtà è che l'ordinamento sta per essere altrettanto veloce in PHP o MySQL. Spesso, a meno che non abbia a che fare con 1000 o milioni di righe, la velocità non è un problema.

Problemi correlati