在数据库中手动设置前 10 个产品的顺序

Gul*_*han 4 sql-server sql-server-2014

我正在为一个商场创建一个数据库。客户想要手动设置前 10 个品牌或商店。他想随时手动设置订单,例如:

store_Name     priority
Puma             1
Reebok           2
Dominos          3
Nike             4
NumeroUno        5
Run Code Online (Sandbox Code Playgroud)

产品将按优先顺序展示给用户。优先级 1 将显示在顶部。

我的问题是当我想更改商店名称的优先级时,例如我希望耐克显示在搜索顶部。

当我将耐克的优先级设置为 1 时,自动现有的 1 个位置变为 2,2 个位置变为 3,依此类推。如何在 SQL Server(存储过程或触发器)中执行此机制?

我正在使用 SQL Server 2014,我的表有数千个商店。我想要 10 个选择性存储,显示在移动应用程序的顶部。

Joe*_*ish 5

只是为了好玩,您可以设计一个数据模型,将一行更新为 N 级需要您扫描 N 行并仅更新 1 的值。显示前 N 个等级也需要您扫描 N 行。一个弱点是过滤到第 N 行还需要您扫描 N 行。如果有人在他们的表中有很多行并且不想潜在地更新数百万行来执行单个排名更改,那么这可能会很有用。

关键是为与显示的排名不同但仍按正确顺序排列的排名存储单独的内部值。这里我将内部优先级存储为NUMERIC(10,6). 对于每次更新,我们可以找到先前的RAW_PRIORITY值并0.000001从中减去。这将保留单行更新的顺序。凭借这种精确度,最终用户在问题开始发生之前最多可更改项目的等级一百万次。精度和规模可以根据您的要求进一步提高。

定义表:

DROP TABLE IF EXISTS dbo.X_STORES;

CREATE TABLE dbo.X_STORES (STORE_NAME VARCHAR(100), RAW_PRIORITY NUMERIC(10,6));

INSERT INTO dbo.X_STORES VALUES
('Puma',1),
('Reebok',2),
('Dominos',3),
('Nike',4),
('NumeroUno',5)

CREATE INDEX X_STORES__PRIORITY ON dbo.X_STORES (RAW_PRIORITY) INCLUDE (STORE_NAME);
Run Code Online (Sandbox Code Playgroud)

根据确切的要求,将表聚集在 上可能是有意义的RAW_PRIORITY。我们还想要一个视图,可以轻松地以人类可读的格式显示排名,并使更新更容易:

CREATE OR ALTER VIEW dbo.X_STORES_PRIORITY_ORDER
AS
SELECT STORE_NAME, ROW_NUMBER() OVER (ORDER BY RAW_PRIORITY) [PRIORITY], RAW_PRIORITY
FROM dbo.X_STORES;
Run Code Online (Sandbox Code Playgroud)

根据我们的开始日期,Nike 排在第 4 位:

SELECT STORE_NAME, [PRIORITY]
FROM dbo.X_STORES_PRIORITY_ORDER
ORDER BY [PRIORITY];
Run Code Online (Sandbox Code Playgroud)

结果:

?????????????????????????
? STORE_NAME ? PRIORITY ?
?????????????????????????
? Puma       ?        1 ?
? Reebok     ?        2 ?
? Dominos    ?        3 ?
? Nike       ?        4 ?
? NumeroUno  ?        5 ?
?????????????????????????
Run Code Online (Sandbox Code Playgroud)

让我们把耐克改成第二:

UPDATE dbo.X_STORES
SET RAW_PRIORITY = (
    SELECT v.RAW_PRIORITY - 0.000001
    FROM dbo.X_STORES_PRIORITY_ORDER v
    ORDER BY v.RAW_PRIORITY OFFSET 1 ROW FETCH NEXT 1 ROW ONLY
)
WHERE STORE_NAME = 'Nike';
Run Code Online (Sandbox Code Playgroud)

结果:

?????????????????????????
? STORE_NAME ? PRIORITY ?
?????????????????????????
? Puma       ?        1 ?
? Nike       ?        2 ?
? Reebok     ?        3 ?
? Dominos    ?        4 ?
? NumeroUno  ?        5 ?
?????????????????????????
Run Code Online (Sandbox Code Playgroud)

现在让我们将 Dominos 更改为第一个:

UPDATE dbo.X_STORES
SET RAW_PRIORITY = (
    SELECT v.RAW_PRIORITY - 0.000001
    FROM dbo.X_STORES_PRIORITY_ORDER v
    ORDER BY v.RAW_PRIORITY OFFSET 0 ROW FETCH NEXT 1 ROW ONLY
)
WHERE STORE_NAME = 'Dominos';
Run Code Online (Sandbox Code Playgroud)

结果:

?????????????????????????
? STORE_NAME ? PRIORITY ?
?????????????????????????
? Dominos    ?        1 ?
? Puma       ?        2 ?
? Nike       ?        3 ?
? Reebok     ?        4 ?
? NumeroUno  ?        5 ?
?????????????????????????
Run Code Online (Sandbox Code Playgroud)