mysql获取按多列排序的下一行
我有一个产品数据库。当我选择一个产品时,我想获得数据库中的下一个产品 例如: 我有ID为188的产品,我想得到下一个ID为167的产品 数据库:mysql获取按多列排序的下一行,mysql,sql,database,range,row,Mysql,Sql,Database,Range,Row,我有一个产品数据库。当我选择一个产品时,我想获得数据库中的下一个产品 例如: 我有ID为188的产品,我想得到下一个ID为167的产品 数据库: SELECT * FROM product ORDER BY title ASC, description ASC +----+----------------------+----------------------+ | id | title | description | +----+-------
SELECT * FROM product ORDER BY title ASC, description ASC
+----+----------------------+----------------------+
| id | title | description |
+----+----------------------+----------------------+
|111 | Adjusterhouse | Finetuning |
+----+----------------------+----------------------+
|188 | Adjustment housing | Height |
+----+----------------------+----------------------+
|167 | Adjustment housing | Oilpressure |
+----+----------------------+----------------------+
|105 | Adjustment housing | Suspension |
+----+----------------------+----------------------+
|102 | Adjustment nut L+R. | Packaging machinery |
+----+----------------------+----------------------+
但是如果我使用下面的SQL语句,我得到的产品ID是102而不是167
SELECT * FROM product
WHERE title > ? AND (title > ? OR description > ?)
ORDER BY title ASC, description ASC LIMIT 1
有人能帮我处理这条SQL语句吗?你用
对标题进行排序。假设您有记录188,标题是调整壳
,如果您查看,您将设置第一条记录,标题是调整壳
,实际上是记录102
将其更改为:
SELECT * FROM product
WHERE title >= ? AND description >= ? AND id != ?
ORDER BY title ASC, description ASC, id ASC LIMIT 1
在准备好的station参数绑定中将第二个
?
替换为id 188您的方法是正确的。只需要一个小的更改,将第一个比较更改为“大于或等于”,而不仅仅是“大于”
只要(title,description)
元组是唯一的,就可以正常工作。这是您想要的模式:
WHERE ( title >= ? )
AND ( title > ? OR description > ? )
(唯一的变化是您需要一个“标题”
=”比较作为中的第一个条件,其中
。您拥有的其他一切都很好
如果
(标题、说明)
元组不能保证唯一…
我们需要在排序中添加额外的列。id
列看起来是一个理想的候选者。这会变得有点复杂,但模式类似
WHERE ( title >= ? )
AND ( title > ? OR
(
( description >= ? )
AND ( description > ? OR id > ? )
)
)
ORDER BY title ASC, description ASC, id ASC
请注意,我们嵌套了相同的模式;description
和id
使用的模式与title
和description
使用的模式相同
外部部分仍然是相同的模式,但是现在它在
标题上,而不是简单的描述,我们得到了在(description,id)
元组上工作的条件。您的用例没有很好的定义,但是实现这一点的一种方法是通过限制子句
因此,以下查询将返回第一行:
SELECT *
FROM product
ORDER BY title ASC, description ASC LIMIT 0, 1
将返回118,调整室,微调
然后,您可以使用:
SELECT *
FROM product
ORDER BY title ASC, description ASC LIMIT 1, 1
返回111,调整壳体,高度
您需要使用选择(COUNT(1)-1)作为产品的最大偏移量
来了解数据“偏移”的距离。最大偏移量始终是行数减去1。在示例数据中,最大偏移量为:
SELECT *
FROM product
ORDER BY title ASC, description ASC LIMIT 4, 1
希望有帮助!这种方法(使用偏移量)当你进入数千行的偏移量时,使用大型集合可能会非常昂贵。OP方法可能更有效,可以快速跳过不需要的行。对。正如我所说,用例没有很好的定义。我显然没有足够的技能来完整地回答这个问题。但是,现在在做什么是的,这是一个好问题。我假设为占位符提供的值是为先前获取的(当前显示的)值行。除了大集合的性能问题外,这种方法不处理插入到当前行下方的行。如果在此期间插入标题较低的行,则上一次查询中的第4行可以是下一次查询中的第5行,从而使下一次提取返回同一行。删除标题较低的行可能会导致n行被“跳过”。同意。我再说一遍,以澄清用例没有得到很好的定义。我做了两个假设:1)此产品表没有频繁添加到中,2)此产品表不超过数千行。在返回row id=167后,后续执行将再次返回row id=188。然后id=167。然后id=188。该算法将在这两行上卡住。您是对的,如果我们不能保证(标题、说明)的正确性,我们需要在订单中引入id
元组不是唯一的。@spencer7593忘记在clause@spencer7593当然,如果有重复的描述,你会得到同样的问题。有可能有重复的标题和描述吗?+1。这是正确的方法。只要将第一个大于比较值的值改为大于或等于。只要(标题、说明)
是唯一的,您就会很好。(我们在这里显然假设为占位符提供的值是上次获取(当前显示)的值)行。如果它不是唯一的,我们需要引入另一个列以使其唯一,看起来id
将是一个理想的候选者。根据您的数据,这是不必要的。谢谢,我现在这样得到它:从产品中选择*,其中title>=?和(title>=?)或((description>=?)和(description>或id>?)按标题ASC、描述ASC、id、ASC限制1排序,我认为效果很好,谢谢。@rrayy:我觉得where子句很合适。(必须提供标题
值两次,说明
值两次,以及id
值一次。相同的模式可以扩展为使用第四列。如果您想按“颜色”或“单价”或其他方式订购。包括主键值(我假设id是主键)因为最后一行确保排序是确定的,并且在ORDER BY
中没有两行具有完全相同的值。