sql - 如何明智地按一组增加列

标签 sql sql-server sql-update sql-order-by

我有一张 table 叫 productLocation ,其数据结构如下,SQLFiddle

+--------------+-------------+-----------+
| FkLocationId | FkProductId | SortValue |
+--------------+-------------+-----------+
| 1            | 100         | 0         |
+--------------+-------------+-----------+
| 1            | 101         | 0         |
+--------------+-------------+-----------+
| 1            | 102         | 0         |
+--------------+-------------+-----------+
| 1            | 103         | 2         |
+--------------+-------------+-----------+
| 1            | 104         | 1         |
+--------------+-------------+-----------+
| 1            | 105         | 3         |
+--------------+-------------+-----------+
| 2            | 100         | 0         |
+--------------+-------------+-----------+
| 2            | 101         | 0         |
+--------------+-------------+-----------+
| 2            | 102         | 0         |
+--------------+-------------+-----------+
| 2            | 103         | 1         |
+--------------+-------------+-----------+
| 2            | 104         | 3         |
+--------------+-------------+-----------+
| 2            | 105         | 2         |
+--------------+-------------+-----------+
| 3            | 100         | 0         |
+--------------+-------------+-----------+
| 3            | 101         | 0         |
+--------------+-------------+-----------+
| 3            | 102         | 0         |
+--------------+-------------+-----------+
| 3            | 103         | 1         |
+--------------+-------------+-----------+
| 3            | 104         | 2         |
+--------------+-------------+-----------+

每个位置都有自己的产品排序顺序。但部分产品有 0 SortValue现在我需要写一个查询来更新 SortValue作为,

如果我考虑一个地点,FkLocationId = 1
+--------------+-------------+-----------+
| FkLocationId | FkProductId | SortValue |
+--------------+-------------+-----------+
| 1            | 100         | 0         |
+--------------+-------------+-----------+
| 1            | 101         | 0         |
+--------------+-------------+-----------+
| 1            | 102         | 0         |
+--------------+-------------+-----------+
| 1            | 103         | 2         |
+--------------+-------------+-----------+
| 1            | 104         | 1         |
+--------------+-------------+-----------+
| 1            | 105         | 3         |
+--------------+-------------+-----------+

在上面的数据表中,可以看到,FkProductId = 100,101,102 0 SortValue .我需要更新它的 sortValueFkProductId 订购降序排列。我需要更新它喜欢
+--------------+-------------+-----------+
| FkLocationId | FkProductId | SortValue |
+--------------+-------------+-----------+
| 1            | 100         | 3         |
+--------------+-------------+-----------+
| 1            | 101         | 2         |
+--------------+-------------+-----------+
| 1            | 102         | 1         |
+--------------+-------------+-----------+

并且也一一更新之前的SortValue。

那么完整的输出应该是,
+--------------+-------------+-----------+
| FkLocationId | FkProductId | SortValue |
+--------------+-------------+-----------+
| 1            | 100         | 3         |
+--------------+-------------+-----------+
| 1            | 101         | 2         |
+--------------+-------------+-----------+
| 1            | 102         | 1         |
+--------------+-------------+-----------+
| 1            | 103         | 5         |
+--------------+-------------+-----------+
| 1            | 104         | 4         |
+--------------+-------------+-----------+
| 1            | 105         | 6         |
+--------------+-------------+-----------+

这是可能的吗?我真的很困惑,请帮我解决这个问题。谢谢

更新:

假设我有另一张 table 作为产品。其数据结构如下,
+-----------+-----------+
| ProdcutId | SortValue |
+-----------+-----------+
| 100       | 0         |
+-----------+-----------+
| 101       | 0         |
+-----------+-----------+
| 107       | 0         |
+-----------+-----------+
| 108       | 1         |
+-----------+-----------+
| 109       | 2         |
+-----------+-----------+
| 110       | 6         |
+-----------+-----------+
| 111       | 5         |
+-----------+-----------+
| 112       | 4         |
+-----------+-----------+
| 113       | 3         |
+-----------+-----------+

我也需要为这张 table 做同样的事情,我该怎么做

预期输出:
+-----------+-----------+
| ProdcutId | SortValue |
+-----------+-----------+
| 100       | 3         |
+-----------+-----------+
| 101       | 2         |
+-----------+-----------+
| 107       | 1         |
+-----------+-----------+
| 108       | 4         |
+-----------+-----------+
| 109       | 5         |
+-----------+-----------+
| 110       | 9         |
+-----------+-----------+
| 111       | 8         |
+-----------+-----------+
| 112       | 7         |
+-----------+-----------+
| 113       | 6         |
+-----------+-----------+

最佳答案

以下是一个示例查询,供您使用 CTE- 检查更新过程并使用相同的逻辑

DEMO HERE

重要提示:更新是一个冒险的过程,您应该先尝试使用您的测试数据。

WITH CTE
AS
(
    SELECT *,
    (
        SELECT COUNT(*) 
        FROM #Temp B 
        WHERE B.FkLocationId = A.FkLocationId
        AND SortValue = 0
    ) Zero_Count,
    -- The above Zero count is a simple count of rows with 0
    -- for a specific FkLocationId. This is for adding to other 
    -- rows where there are already value in column SortValue. The logic
    -- is simple, the number of row with 0 in column SortValue, 
    -- should be add to existing value where there is value not equal 0.
    ROW_NUMBER() OVER (PARTITION BY FkLocationId ORDER BY SortValue ASC, FkProductId DESC) RN
    -- ROW_NUMBER is simply creating the Number you should replace 0 by.
    -- As you are looking for 1 to start for the MAX FkProductId with 0,
    -- I applied DESC order on that column
    FROM #Temp A
) 

UPDATE A
SET A.SortValue = 
CASE 
    WHEN A.SortValue = 0 THEN B.RN 
    -- RN is created in such way, so that you can directly 
    -- Replace your value in column SortValue by RN if SortValue = 0 
    ELSE A.SortValue + B.Zero_Count
    -- IF SortValue contains already value > 0, 
    -- You need to just increment the value with Number 
    -- of rows is there with value 0. I have calculated that value
    -- by a sub query in the CTE you can check.
END
FROM  #Temp A
INNER JOIN CTE B ON A.FkLocationId = B.FkLocationId
AND A.FkProductId = B.FkProductId


SELECT * FROM #Temp

Just use your "table_name" where I have used #temp

关于sql - 如何明智地按一组增加列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62166993/

相关文章:

mysql - 更新加入 -> 插入 NULL

sql - Netezza 通过连接到另一个表来更新表列

php - php 中不同的 if 语句

MySQL 查询根据不同条件连接 4 个表

sql - 如何获取 SQL Server 查询的近似结果行数

SQL 从 null、0 和 1 范围内选择具有 Null 和 0 值的值

sql - 根据表B中的记录更新表A中的记录

sql - 如何避免有太多相似的列?

sql-server - 具有多个非透视列的 T-SQL 透视

sql - 如果子查询在 Postgres 中返回多行,则跳过行