Mysql:查询默认有哪些订单和排名(pin/hold上条目?)
Mysql: Query which orders by default and rank (pin/hold up entries?)
我有一个产品 table,其中包含我所有的产品。这些产品 table 会永久填充新产品。但是,我希望有可能将某些产品“保留”/“固定”到返回的查询集合中的某个位置。
意思是,我想设置类似 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
4 的产品设置的,所以我想获得具有以下返回 ID 顺序的集合:1, 4, 3, 5, 2
.
这有可能吗? rank_index
专栏只是我的一个想法。我的意思是.. 我也可以在 php
端执行此操作并执行一个正常查询,该查询仅包含 products
而不包含 rank_index
和仅包含 products
的查询index_rank
并在 php
端手动订购它们。
但是,因为这需要大量时间和处理能力,所以我正在寻找一个由数据库完成的解决方案...有什么想法吗?
顺便说一句:如果这有什么不同的话,我正在使用 Laravel 8。
亲切的问候
如果不为 null,则使用 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', NULL),
('4', 'Green carpet', '2'),
('5', 'Toy', NULL);
SELECT *
FROM table1
ORDER BY IF(rank_index IS NULL, id, 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<>fiddle here
这是一个非常棘手的问题。如果您尝试设置连续值的其他方法——例如 2 和 3——您会发现它们不起作用。
可能有更简单的方法来解决这个问题。但是,这是一种蛮力方法。
- 它通过枚举原始table中的行构造派生table。
- 它将所有 force-ranked 值添加到此 table(使用
left join
)中。
- 它通过枚举
table1
和派生的 table. 中的空槽来加入其余值
所以:
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;
我有一个产品 table,其中包含我所有的产品。这些产品 table 会永久填充新产品。但是,我希望有可能将某些产品“保留”/“固定”到返回的查询集合中的某个位置。
意思是,我想设置类似 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
4 的产品设置的,所以我想获得具有以下返回 ID 顺序的集合:1, 4, 3, 5, 2
.
这有可能吗? rank_index
专栏只是我的一个想法。我的意思是.. 我也可以在 php
端执行此操作并执行一个正常查询,该查询仅包含 products
而不包含 rank_index
和仅包含 products
的查询index_rank
并在 php
端手动订购它们。
但是,因为这需要大量时间和处理能力,所以我正在寻找一个由数据库完成的解决方案...有什么想法吗?
顺便说一句:如果这有什么不同的话,我正在使用 Laravel 8。
亲切的问候
如果不为 null,则使用 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', NULL),
('4', 'Green carpet', '2'),
('5', 'Toy', NULL);
SELECT *
FROM table1
ORDER BY IF(rank_index IS NULL, id, 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<>fiddle here
这是一个非常棘手的问题。如果您尝试设置连续值的其他方法——例如 2 和 3——您会发现它们不起作用。
可能有更简单的方法来解决这个问题。但是,这是一种蛮力方法。
- 它通过枚举原始table中的行构造派生table。
- 它将所有 force-ranked 值添加到此 table(使用
left join
)中。 - 它通过枚举
table1
和派生的 table. 中的空槽来加入其余值
所以:
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;