【问题标题】:order by field with more than 10000 ids按超过 10000 个 id 的字段排序
【发布时间】:2011-05-19 05:39:20
【问题描述】:

我需要使用 order by field 进行特定排序。

select * from table order by field(id,3,4,1,2.......upto 10000 ids)

由于无法从 SQL 中获取所需的排序,那么它对性能的影响有多大,是否可行?

来自 cmets 的更新:

  • 排序取决于用户和类别 ID,可以是用户想要的任何东西。
  • 订购规格每天(大约)变化。

因此,我们需要一个取决于用户和类别的自定义排序,并且此排序需要每天更改。

【问题讨论】:

  • 您的意思是最多 10000 列吗?按字段排序并不难;在该字段上建立一个索引,你就完成了。
  • @bdares:我希望 jit 并不意味着 10000 列。 @jit,您的意思是您有 10000 行,并且您想以某种不依赖于 id 的自定义格式对它们进行排序吗?
  • 是的,@mu 太短了,我说得对……
  • 如果您想在记录中设置某种自定义顺序,为什么不添加一列来保存此顺序并在其上建立索引?
  • 订单是用户特定的,并在我们每天为每个用户获取和显示结果时生成.....

标签: sql field sql-order-by


【解决方案1】:

最简单的方法是将您的订单放在一个单独的表中(在本例中称为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 NULLUNIQUE 约束,以确保您涵盖所有内容并具有一致的排序.

进一步的评论表明您希望为不同的用户和类别提供不同的排序,并且排序每天都会发生变化。您可以为每个条件创建单独的表(这会导致组合爆炸),或者,正如 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_iduser_idcategory_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 和类别 ID。请注意对 LEFT JOIN 的更改和添加 COALESCE 以允许在 ordering_table 中丢失行,这些更改会将顺序中没有指定位置的任何内容推到列表的底部,而不是从列表中删除它们结果完全。

【讨论】:

  • @jit:所以每个用户都有一个排序表,并且排序表每天都会更新。
  • 如果将 UserID 列添加到 ordering_table 中,则不需要为每个用户创建一个表。用户可以在同一张表中维护单独的排序。
  • @jit:所以,您只需在此表中再添加两列:useridcategoryid
  • @Mikael、@ypercube、@jit:我认为 ypercube 的用户和类别列到排序表的想法比一堆单独的表更有意义,所以我将更新答案以反映这一点。当我应该退后一点时,我在精神上被锁定在“单独的桌子”中并继续使用它;但这就是 cmets 的用途。
  • 让它成为一个临时表,如果每次订单都不同,则在用户指定订单时构建。否则,使其成为一个永久表,该表也具有 user_id/category_id。如果您使用永久表,则需要设置一种在将新记录添加到原始表时添加新记录的方式。
猜你喜欢
  • 1970-01-01
  • 2020-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多