我有一个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
,它以看似随机的顺序将其拉出。
答案 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%,但你不应该过多地依赖空值(因为这不是官方保证)