我products在MySQL数据库中有一个表。products看起来像这样:
products
id name din strength active deleted 1 APA TEST 00246374 25 1 0 4 APA BOB 00246375 50 1 0 5 APA TIRE 00246888 50 1 0 7 APA ROT 00521414 100 1 0 9 APA APA 01142124 100 1 0 6 APA CODE 00121212 150 1 0 8 APA SERV 00011145 600 1 0
显然,我省略了对我的问题不重要的几列。当查询该表时,我将按几个不同的列之一进行排序(用户界面允许单个用户更改排序列和顺序),并且我可能会有一个搜索子句,在这种情况下,我将对名称和DIN。
我想知道的是,给定排序信息和搜索信息以及特定产品的ID(例如,我搜索004,该结果返回了3个结果,并且我正在查看其中一个结果),如何获得下一个结果和以前的产品?
我需要这样做,因为如果用户在搜索和排序结果后单击以编辑/查看其中一种产品,那么他们希望能够在不转到上一页的情况下循环浏览结果。
在SQL中是否有一种良好且高效的方法来执行此操作,还是我最好使用PHP?任何想法也欢迎。
当前正在使用此SQL查询,如果我按strength列进行排序,因为存在重复的值,则会遇到问题
strength
SELECT T.* FROM `wp_products` T INNER JOIN `wp_products` curr on curr.id = 38 AND ((T.strength = curr.strength and T.id < curr.id) OR (T.strength > curr.strength)) WHERE T.active = 1 AND T.deleted = 0 AND (T.name LIKE '%%' OR T.din LIKE '%%') ORDER BY T.strength ASC, T.id ASC LIMIT 1
我的PHP代码(使用WordPress)(旨在获取下一项)
$sql = 'SELECT T.* FROM `' . $wpdb->prefix . 'apsi_products` T INNER JOIN `' . $wpdb->prefix . 'apsi_products` curr on curr.id = ' . $item->id . ' AND ((T.' . $wpdb->escape( $query['orderby'] ) . ' = curr.' . $wpdb->escape( $query['orderby'] ) . ' and T.id > curr.id) OR (T.' . $wpdb->escape( $query['orderby'] ) . ' > curr.' . $wpdb->escape( $query['orderby'] ) . ')) WHERE T.active = 1 AND T.deleted = 0 AND (T.name LIKE \'%' . $query['where'] . '%\' OR T.din LIKE \'%' . $query['where'] . '%\') ORDER BY T.' . $wpdb->escape( $query['orderby'] ) . ' ' . $query['order'] . ', T.id ASC LIMIT 1;';
您需要引用当前记录,然后根据已排序的列逐步查找下一条记录。下面的示例假定它已排序
ORDER BY Active, DIN, NAME
第一的:
SELECT * FROM TABLE WHERE NAME LIKE '%X%' AND DIN LIKE '%%' ORDER BY Active, DIN, Name LIMIT 1;
下一步:(请 确保CURR.ID = 6使用正确的括号将AND和AND或OR分开!)
CURR.ID = 6
SELECT * FROM TABLE T INNER JOIN TABLE CURR ON CURR.ID = 6 # the current ID being viewed AND ((T.Active = Curr.Active AND T.DIN = Curr.DIN AND T.NAME > Curr.Name) OR (T.Active = Curr.Active AND T.DIN > Curr.DIN) OR T.Active > Curr.Active) WHERE T.NAME LIKE '%X%' AND T.DIN LIKE '%%' ORDER BY T.Active, T.DIN, T.Name LIMIT 1;
下面提供了一个工作样本
create table products (ID int, SEED int, NAME varchar(20), DIN varchar(10), ACTIVE int, DELETED int); insert products values (1, 0, 'Product #1', '004812', 1, 0), (2, 0, 'Product #2', '004942', 0, 0), (3, 0, 'Product #3', '004966', 1, 0), (4, 0, 'Product #4', '007437', 1, 1), (5, 2, 'Product #2', '004944', 0, 0), (6, 2, 'Product #2', '004944', 1, 0); SELECT * FROM products WHERE active = 1 AND deleted = 0 ORDER BY din DESC, ID desc; Output: "ID";"SEED";"NAME";"DIN";"ACTIVE";"DELETED" "3";"0";"Product #3";"004966";"1";"0" "6";"2";"Product #2";"004944";"1";"0" "1";"0";"Product #1";"004812";"1";"0"
如果当前是ID = 6的行,则可以使用检索下一条记录
SELECT T.* FROM products T INNER JOIN products curr on curr.ID = 6 AND ((T.din = curr.din and T.ID > curr.ID) OR (T.din < curr.din)) WHERE T.active = 1 AND T.deleted = 0 ORDER BY T.din DESC, T.ID ASC LIMIT 1;