我需要按字段顺序进行特定排序。
select * from table order by field(id,3,4,1,2.......upto 10000 ids)
由于SQL无法获得所需的排序,因此它对性能的影响程度是多少,是否可行?
评论更新:
因此,我们需要一个取决于用户和类别的自定义排序,这种排序需要每天更改。
答案 0 :(得分:4)
最简单的方法是将您的订单放在一个单独的表中(在本例中称为ordering_table
):
id | position
----+----------
1 | 11
2 | 42
3 | 23
etc.
上述意思是“将id
1置于第11位,2位于第42位,3位置在第23位,......”。然后,您可以加入该订购表:
SELECT t.id, t.col1, t.col2
FROM some_table t
JOIN ordering_table o ON (t.id = o.id)
ORDER BY o.position
ordering_table
是表(如上所述)定义您的奇怪排序的地方。这种方法只是将您的排序函数表示为一个表(任何具有有限域的函数,基本上只是一个表)。
只要订购表完整,这种“订购表”方法就可以正常工作。
如果您只需要在一个地方进行这种奇怪的排序,那么您可以将position
列合并到主表中,并在该列上添加NOT NULL
和UNIQUE
限制以确保覆盖一切都有一致的顺序。
进一步评论表明您需要针对不同用户和类别的不同排序,并且订单将每天更改。您可以为每个条件创建单独的表(这会导致组合爆炸),或者如Mikael Eriksson和ypercube建议的那样,在订购表中添加几列以保存用户和类别:
CREATE TABLE ordering_table (
thing_id INT NOT NULL,
position INT NOT NULL,
user_id INT NOT NULL,
category_id INT NOT NULL
);
thing_id
,user_id
和category_id
将是各自表的外键,您可能希望索引ordering_table
中的所有列但是一对分钟查看查询计划是值得的,看看索引是否值得使用。您还可以将所有四列作为主键以避免重复。然后,查询查询将是这样的:
SELECT t.id, t.col1, t.col2
FROM some_table t
LEFT JOIN ordering_table o
ON (t.id = o.thing_id AND o.user_id = $user AND o.category_id = $cat)
ORDER BY COALESCE(o.position, 99999)
其中$user
和$cat
分别是用户和类别ID。注意对LEFT JOIN的更改以及添加COALESCE以允许ordering_table
中缺少行,这些更改会将顺序中没有指定位置的任何内容推送到列表底部而不是删除它们从结果中完全。