问题描述
我有一个产品表,其中包含我所有的产品。这些产品表将永久充满新产品。但是,我希望可以将某些产品“保留” /“固定”在返回的查询集合中的某个位置。
方法是,我想设置rank_index
之类的内容,其中包含产品在返回的查询集合中应具有的编号。
示例:
id title rank_index
1 An awesome product
2 Another product 5
3 Baby car
4 Green carpet 2
5 Toy
让我们假设默认顺序为id
。但是因为rank_index
是为产品id
设置的,所以我想以以下ID顺序返回集合:1,4,3,5,2
。
这有可能做到吗? rank_index
列只是我的一个想法。我的意思是..我也可以在PHP
端执行此操作,并执行一个普通查询,该查询仅包含products
而没有rank_index
,而仅包含{ products
并在index_rank
端手动订购。
但是,因为这需要大量时间和处理能力,所以我正在寻找由数据库完成的解决方案……有什么想法吗?
顺便说一句:如果有什么不同,我正在使用Laravel 8。
亲切的问候
解决方法
如果rank_index
的顺序不为空,请使用id
;否则,请使用
由于您希望rank_index
领先于id
,因此进行了-0.5
调整:
SELECT *
FROM table
ORDER BY IF(rank_index IS NULL,id,rank_index - 0.5)
,
您可以使用IF
子句并获得正确的数字来获得正确的顺序,所以
CREATE TABLE table1 (
`id` INTEGER,`title` VARCHAR(18),`rank_index` INT
);
INSERT INTO table1
(`id`,`title`,`rank_index`)
VALUES
('1','An awesome product',NULL),('2','Another product','5'),('3','Baby car',('4','Green carpet','2'),('5','Toy',NULL);
SELECT *
FROM table1
ORDER BY IF(rank_index IS NULL,rank_index + .01)
+----+--------------------+------------+
| id | title | rank_index |
+----+--------------------+------------+
| 1 | An awesome product | NULL |
| 4 | Green carpet | 2 |
| 3 | Baby car | NULL |
| 5 | Toy | NULL |
| 2 | Another product | 5 |
+----+--------------------+------------+
db 提琴here
,这是一个非常棘手的问题。如果您尝试其他方法来设置连续的值(例如2和3),则会发现它们不起作用。
可能有更简单的方法来解决此问题。但是,这是一种蛮力方法。
- 它通过枚举原始表中的行来构造派生表。
- 它将所有强制排名值添加到该表中(使用
left join
)。 - 通过枚举
table1
和派生表中的空插槽,它加入了其余的值。
所以:
with recursive n as (
select row_number() over (order by id) as n
from table1 t1
),nid as (
select n.n,t1.id
from n left join
table1 t1
on t1.rank_index = n.n
),nids as (
select n.n,coalesce(n.id,t1.id) as id
from (select nid.*,sum(nid.id is null) over (order by nid.n) as seqnum
from nid
) n left join
(select t1.*,row_number() over (order by id) as seqnum
from table1 t1
where rank_index is null
) t1
on n.seqnum = t1.seqnum
)
select t1.*
from nids join
table1 t1
on t1.id = nids.id
order by nids.n;