代码之家  ›  专栏  ›  技术社区  ›  James Skidmore

如何在MySQL中按默认排序顺序显式排序?

  •  2
  • James Skidmore  · 技术社区  · 14 年前

    我有一个mysql表,其中有两个字段组成主键,还有一个“sort”字段。这些都不是自动递增的。

    在不指定 ORDER BY 子句,它按照放入的顺序提取数据——相当标准。所以无论哪一行先插入,它都会先将它们拉出。

    问题是当我 ORDER BY sort ASC 如果 sort 如果为空,那么它实际上根本不排序,结果就会变得混乱。但我想有后援 排序依据 是它将退出的默认顺序。我不能让备份成为自动递增的“id”字段,因为没有自动递增的id字段。主键只是两个外键的组合。

    -----编辑-----

    表:

    CREATE TABLE IF NOT EXISTS `product_attribute_select_value` (
      `product_attribute_id` int(11) NOT NULL,
      `attribute_select_value_id` int(11) NOT NULL,
      `sort` int(11) default '0',
      PRIMARY KEY  (`product_attribute_id`,`attribute_select_value_id`),
      KEY `product_attribute_select_value_FI_2` (`attribute_select_value_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    ALTER TABLE `product_attribute_select_value`
      ADD CONSTRAINT `product_attribute_select_value_FK_1` FOREIGN KEY (`product_attribute_id`) REFERENCES `product_attribute` (`id`) ON DELETE CASCADE,
      ADD CONSTRAINT `product_attribute_select_value_FK_2` FOREIGN KEY (`attribute_select_value_id`) REFERENCES `attribute_select_value` (`id`);
    

    数据:

    数据被插入,并且在不使用 按顺序 从句,它是按顺序排列出来的。当有一个 按顺序 条款和所有 分类 价值观是 0 它以一个看似随机的顺序把它拉出来。

    4 回复  |  直到 14 年前
        1
  •  1
  •   o.k.w    14 年前

    我知道你想要什么,但不能真正拿出完美的解决方案。

    以下是我的两个选择:

    • 在应用程序中排序
    • 添加时间戳列或 为了 备份排序: .... ORDER BY sort, SORTCOLUMN ASC
        2
  •  5
  •   mjv    14 年前

    首先,重要的是要知道,在没有逐条订购的情况下, SQL标准没有规定SQL实现以任何特定顺序生成行。 ,事实上,对于类似的查询,甚至没有期望生成的订单是一致的!

    因此,依赖实现提供的“自然顺序”的想法通常是危险的,除非特定DBMS生产者明确记录(我不相信MySQL就是这样),否则这种“自然顺序”随时都可能发生变化(任何新版本、数据库中的任何内容变化,甚至!)

    但是,有一个处理空值的技巧:

    ORDER BY COALESCE(sort, 'zzzzzzz') 
    

    其中“zzzzzz”是大于或小于“sort”列的任何预期值的值,继续将空行放在末尾或开头。我们通常使用这种技术来覆盖MySQL的默认行为,即将空值视为最小值,因此将第一个放在“asc”排序中,最后一个放在“desc”排序中。
    这个 working with null values 在mysql文档中。

    也可以为排序添加一个额外的列,例如

    ORDER BY COALESCE(sort, 'zzzzzzz') , id
    
        3
  •  2
  •   Ryan Elkins    14 年前

    如果没有ORDERBY子句,就无法保证行的返回顺序。它们通常按照插入的顺序返回,但同样,这不是您真正可以依赖的东西。最好的办法是添加一个自动递增的ID,作为备份进行排序。这将允许您根据插入顺序进行排序,如果您希望备份排序是这样的话。

        4
  •  0
  •   noonex    14 年前

    为了确保索引用于排序,您还可以尝试以下方法:

    select ... where sort is not null order by sort asc
    union
    select ... where sort is null
    

    这应该在99%的情况下有效,但是你不应该过分依赖于空值将在最后出现(因为这不是官方保证)。