How to increment column by one group wise

最后都变了- 提交于 2020-06-16 03:35:33

问题


I have a table called productLocation, and its data structure as follows, 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         |
+--------------+-------------+-----------+

For each location have its own sorting order for products. But some of the products have 0 as the SortValue Now I need to write a query to update SortValue as,

If I consider one location, FkLocationId = 1

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

In the above data table, you can see, FkProductId = 100,101,102 have 0 as the SortValue. I need to update its sortValue as order by FkProductId descending order. I need to update its like

+--------------+-------------+-----------+
| FkLocationId | FkProductId | SortValue |
+--------------+-------------+-----------+
| 1            | 100         | 3         |
+--------------+-------------+-----------+
| 1            | 101         | 2         |
+--------------+-------------+-----------+
| 1            | 102         | 1         |
+--------------+-------------+-----------+

And also update the previous SortValue by one by one.

Then the complete output should be,

+--------------+-------------+-----------+
| FkLocationId | FkProductId | SortValue |
+--------------+-------------+-----------+
| 1            | 100         | 3         |
+--------------+-------------+-----------+
| 1            | 101         | 2         |
+--------------+-------------+-----------+
| 1            | 102         | 1         |
+--------------+-------------+-----------+
| 1            | 103         | 5         |
+--------------+-------------+-----------+
| 1            | 104         | 4         |
+--------------+-------------+-----------+
| 1            | 105         | 6         |
+--------------+-------------+-----------+

Is this possible to do? I'm really confused about this, please help me to solve this. Thank you

Updated:

Suppose I have another table as product. And its data structure as follows,

+-----------+-----------+
| ProdcutId | SortValue |
+-----------+-----------+
| 100       | 0         |
+-----------+-----------+
| 101       | 0         |
+-----------+-----------+
| 107       | 0         |
+-----------+-----------+
| 108       | 1         |
+-----------+-----------+
| 109       | 2         |
+-----------+-----------+
| 110       | 6         |
+-----------+-----------+
| 111       | 5         |
+-----------+-----------+
| 112       | 4         |
+-----------+-----------+
| 113       | 3         |
+-----------+-----------+

I also need to do same thing for this table as well, How can I do it

Expected Output:

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

回答1:


Following is a sample query for you to check and use the same logic for your update process using CTE-

DEMO HERE

Important Note: Update is a risky process and you should try with your test data first.

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




回答2:


with cte as
(select FkLocationId, FkProductId, SortValue,
ROW_NUMBER() over(partition by FkLocationId order by sortvalue,FkProductId desc) new_sort_value
from productLocation where FkLocationId =1  --and SortValue =0
)

update pl SET
pl.SortValue = c.new_sort_value
from productLocation pl inner join cte c
on pl.FkLocationId = c.FkLocationId and pl.FkProductId = c.FkProductId

Select * from productLocation where FkLocationId =1 order by FkProductId

The core of the approach taken by me is based row_number window function, which partitions data over fkproductid sorted by sortvalue and fkproductid in descending manner.

There are 2 queries involved, although could have been done is single, but for simplicity's sake i have used common table expression (cte)

CTE derived from query one is used as joining table in second update query.

I have left much to self exploration, remember its imperative to think in term of sets.



来源:https://stackoverflow.com/questions/62166993/how-to-increment-column-by-one-group-wise

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!