SQL SELECT ...按结果顺序

时间:2013-12-18 10:55:48

标签: mysql

这是场景 - 我有一张桌子

CREATE TABLE IF NOT EXISTS `stylemaps` (
`zyid` varchar(9) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
`styid` varchar(9) CHARACTER SET ascii COLLATE ascii_bin NOT NULL DEFAULT 'zzzz0000Z',
UNIQUE KEY `zyid` (`zyid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

此表中的一组典型条目可能是

zyid        styid
qrst1234    abcd1230
abcd9876    abcd1231
pqzx4569    abcd1232
bcde0000    abcd1233

即。 zyid的条目顺序相当随机。

现在假设我发出

SELECT styid FROM `styles` WHERE zyid in ['abcd9876','bcde0000']

我得到的结果是

abcd1231
abcd1233

即。这些行的排序方式与我的SQL语句中 IN 子句的排序方式相同。

我的问题是 - 我可以依赖于这种情况(只要我正确地命令IN子句条目)吗?

如果这次失败并且我最终错误地映射样式,那么最终结果可能会完全出现乱码。另一种方法是做

SELECT zyid,styid

而不是

SELECT styid

然后对结果做一些工作以保证正确的映射。

4 个答案:

答案 0 :(得分:5)

您可以尝试:

  SELECT styid
    FROM `styles` 
   WHERE zyid IN ['abcd9876','bcde0000']
ORDER BY FIELD(zyid, 'abcd9876','bcde0000')

答案 1 :(得分:2)

不,您不能依赖于IN内容的结果。原因如下:

  • 根据查询优化器选择的最有效顺序,按顺序检查每一行。如果您的WHERE子句中没有其他条件,并且您正在查看所有列(或者没有PRIMARY以外的索引),这意味着优化器选择执行表扫描,因此它会读取所有行以最有效的方式。在您的结果中,这恰好是您第一次输出的顺序。
  • 对于每一行,它会在IN子句中执行binary search个条目。这使得搜索(对于每一行)非常有效,但不会改变行的顺序。

简而言之,使用IN子句时获得的行的顺序与不使用IN子句时获得的顺序没有区别,但是您可以通过更改其他方式的声明,例如使用ORDER BY,给你最大的控制权;或者(如果你有其他索引)通过使用语句中的其他元素来改变优化器读取行的方式。

答案 2 :(得分:0)

AFAIK是您无法信赖的,因为DBMS Optimizer最终会决定首先显示什么。

答案 3 :(得分:-2)

只需在最后添加'order by'子句,例如

SELECT styid FROM `styles` 
WHERE zyid in ['abcd9876','bcde0000']
ORDER BY styid