是否有通过匹配多个条件进行排序的SQL技术?

时间:2010-07-01 22:33:51

标签: php sql mysql sorting

我有几个表连接在一起形成一个包含列

的表
designID
garmentID
colorID
sizeID
imageID

我有一个看起来像这样的函数[方括号中的变量是可选的]:

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

我希望它按以下顺序返回所有匹配$ designID的imageID:

  • 首先匹配$ garmentID,$ colorID和$ sizeID的行
  • 匹配$ garmentID和$ colorID next
  • 的行
  • 仅与$ garmentID匹配的行
  • 与最后一行匹配的行(仅限$ designID)

我可以通过加载匹配$ designID的所有行然后在PHP中对它们进行排序来轻松地完成这项工作,但我的理解是,在可能的情况下在MySQL中进行排序通常会更快。将有大约20行匹配给定的$ designID。

所以我的问题是双重的:是否值得在SQL语句中进行排序?如果我这样做,最好的方法是什么?

我也很想知道这种排序是否有名称。

2 个答案:

答案 0 :(得分:8)

如果我理解正确,看起来您可以在ORDER BY中使用表达式,其方式类似于以下Stack Overflow帖子中接受的答案:

因此,您的查询可能如下所示:

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

请注意,garmentIDcolorIDsizeID不会用作WHERE子句中的过滤器。这些值仅用于ORDER BY表达式。

测试用例:

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

结果:

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)

请注意与指定的garmentIDcolorIDsizeID匹配的行是如何排在第一位的。如果不这样,那么匹配garmentIDcolorID的行就是下一行。然后是仅匹配garmentID的行。然后是其余的,只匹配designID子句的WHERE过滤器。

我相信在SQL中这样做是值得的。作为@Toby noted in the other answer,一般来说,排序这么少的行时你不需要担心性能,假设你总是按designID过滤...至于你的另一个问题,我不喜欢不知道是否有这样一个查询的名称 - 我倾向于称之为“通过表达式排序”。

答案 1 :(得分:2)

这是一个有趣的问题,阅读丹尼尔的回答告诉我一些(复杂的)我不了解的SQL。

然而,

如果你只有20个这样的设计,那么现实是在php或MySQL中排序的速度一样快。通常,除非您处理1000行或数百万行,否则速度不是问题。