2010-07-01 11 views
5

Tengo varias tablas que tienen unido para formar una tabla con columnas¿Hay una técnica de SQL para ordenar al hacer coincidir varios criterios?

designID 
garmentID 
colorID 
sizeID 
imageID 

Tengo una función que tiene este aspecto [variables en corchetes son opcionales]:

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

lo quiero para devolver todos los imageIDs que responden a $ designID en el siguiente orden:

  • filas que coinciden con $ garmentID, colorID $ y $ sizeID primera
  • filas que coinciden con $ garmentID y $ ColorID próximos
  • filas que coinciden con sólo $ garmentID próximos
  • filas que coinciden con ninguna (sólo $ designID) última

que podía hacer esto muy fácilmente con sólo cargar todos las filas que coinciden con $ designID y luego ordenarlas en PHP, pero tengo entendido que generalmente es más rápido hacer la clasificación en MySQL cuando sea posible. Habrá aproximadamente 20 filas que coincidan con un $ designID determinado.

Así que mi pregunta es doble: ¿Vale la pena hacer la clasificación en una declaración de SQL? Si lo hago, ¿cuál es el mejor enfoque para tomar?

También me interesaría saber si hay un nombre para este tipo de clasificación.

Respuesta

8

Si he entendido bien, parece que se puede utilizar expresiones en su ORDER BY, de una manera similar a la respuesta aceptada dado al siguiente post desbordamiento de pila:

tanto , la consulta podría tener este aspecto:

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

Tenga en cuenta que garmentID, colorID y sizeID no se utilizan como filtros en la cláusula WHERE. Los valores solo se usan en las expresiones ORDER BY.

caso de prueba:

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); 

Resultado:

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) 

Nota cómo la fila que coincide con el especificado garmentID, colorID y sizeID es primero. De lo contrario, las filas que coinciden con garmentID y colorID son las siguientes. Luego siguen las filas que solo coinciden con garmentID. Luego, el resto, que solo coincide con el filtro designID de la cláusula WHERE.

Creo que vale la pena hacerlo en SQL. Como @Toby noted in the other answer, en general no necesita preocuparse por el rendimiento al ordenar un número tan pequeño de filas, suponiendo que siempre estará filtrando por designID ... En cuanto a su otra pregunta, no sé si hay un nombre para tal consulta, tiendo a llamarlo "ordenar por una expresión".

+0

Un importante descargo de responsabilidad sobre esta técnica es que las columnas que no coinciden no serán ordenadas; esto puede o no ser un problema para este caso de uso. – Stobor

+0

@Stobor: no creo que lo entiendo. ¿Puedes dar un ejemplo? ... También ten en cuenta que creo que el OP quiere solo una columna en el conjunto de resultados (una columna 'imageId'). –

+1

Esto es exactamente lo que estaba buscando, y considerablemente más elegante de lo que imaginaba. – Robert

2

Este es un problema interesante, y la lectura de la respuesta de Daniel me ha enseñado algo (complicado) que no sabía acerca de SQL.

Sin embargo,

Si sólo está siempre propensos a tener 20 de estos diseños, la realidad es que la clasificación va a ser igual de rápido en PHP o MySQL. A menudo, a menos que trabaje con 1000 o millones de filas, la velocidad no es un problema.

Cuestiones relacionadas