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

时间:2009-11-22 05:17:19

标签: mysql

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

当你在没有指定ORDER BY子句的情况下对表进行查询时,它会按照放入的顺序拉出数据 - 非常标准。因此,无论先插入哪一行,都会先将它们拉出来。

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

----- ----- EDIT

表:

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

数据:

插入数据,在没有ORDER BY子句的情况下拉出数据时,它按照放入的顺序出现。当有ORDER BY子句和所有{{1}时}值为sort,它以看似随机的顺序将其拉出。

4 个答案:

答案 0 :(得分:5)

首先,重要的是要知道,在没有ORDER BY子句的情况下, SQL标准没有规定SQL实现以任何特定顺序生成行,实际上甚至没有期望所产生的订单对于类似的查询是一致的!

因此,依赖于实现提供的“自然顺序”的概念通常是危险的,除非特定DBMS生产者明确记录(我不相信MySQL的情况),这“自然”订单“可以随时更改(任何新版本,数据库中的任何内容更改,甚至!)

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

ORDER BY COALESCE(sort, 'zzzzzzz') 

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

也可以为排序添加额外的列,可能类似

ORDER BY COALESCE(sort, 'zzzzzzz') , id

答案 1 :(得分:2)

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

答案 2 :(得分:1)

我知道你想要什么但却无法提供完美的解决方案。

以下是我的两个选择:

  • 在您的应用中排序
  • 添加时间戳列或 自动增量柱为了 备用排序:.... ORDER BY sort, SORTCOLUMN ASC

答案 3 :(得分:0)

要确保索引用于排序,您可以尝试遵循以下想法:

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

这应该可以达到99%,但你不应该过多地依赖空值(因为这不是官方保证)