2011-03-10 62 views
1

有了这个SQL,我可以使用的可以按字母顺序选择下一个记录,但记录名称相同时会发生什么?

SELECT id 
FROM `names` 
WHERE `name` > (SELECT `name` FROM `names` WHERE `id` = X) 
ORDER BY `name` ASC, `id` ASC 

的ID抢按字母顺序排列的下一个名字但是我们asume我有这方面我有这些记录

id | name 
--------- 
12 | Alex 
8 | Bert 
13 | Bert 
17 | Bert 
4 | Chris 

说我有编号12作为参考我得到的结果

id | name 
--------- 
8 | Bert 
13 | Bert 
17 | Bert 
4 | Chris 

但是,如果使用8作为参考,我得到

id | name 
--------- 
4 | Chris 

Bert 13和17会跳过。

回答

1

尝试这样的条件:

WHERE `name` > (SELECT `name` FROM `names` WHERE `id` = X) 
     OR `name` = (SELECT `name` FROM `names` WHERE `id` = X) AND `id` > X 
+0

当我通过12选择时不会跳过记录8 |亚历克斯 – Moak 2011-03-10 03:44:56

+0

如果你在记录12上,它是'WHERE name>'Alex'OR(name ='Alex'AND id> 12)'。对于第8张专辑,“Bert”>“Alex''所以不会被跳过。 – Anomie 2011-03-10 03:46:54

1

这是因为您正在比较名称与大于运算符,这将排除任何等于的名称。如果你想保持尊重ID:

SELECT n.id 
FROM names n 
JOIN (SELECT name, id FROM names WHERE id = X) q 
    ON n.id = q.id 
WHERE n.name > q.name 
    (OR n.names = q.name AND n.id > q.id) 
ORDER BY n.name ASC, n.id ASC 

这里我们使用内部查询返回不但名字,但也相应的ID。然后,我们可以在同名的情况下使用该id作为打破平局。

2

这似乎是显而易见的,但如果你想通过2个字段,如名字和姓氏订购,那么你将需要连接(CONCAT/CONCAT_WS)的第一和姓氏字段以查找上一个或下一个结果。如果您的名称相同,则可能发现自己正在从一个名称循环到另一个名称,并再次返回,为了防止出现这种情况,请将该行的ID连接到拼接起来的名字和姓氏的末尾。如果ID大于当前ID (OR n.names = q.name AND n.id > q.id),就好像名称没有按字母顺序插入,那么这将比测试更好,那么您将错过结果的部分(而不是浏览到下一个/上一个结果时想要的内容)。希望这可以帮助某人。

+1

是的,这是正确的解决方案,看看这里(||表示concate): 'SELECT ID FROM names WHERE(name || ID)>(SELECT name || ID FROM names WHERE id = X)ORDER BY name ASC;' – MaxV 2013-08-06 08:17:57

相关问题