更新项目记录以匹配非空字段

时间:2019-03-05 20:12:16

标签: sql-server

我有一个带有2个字段的组合键和一个标准字符字段的旧表:Order_Id, Item_Id, Type。我们遇到的问题是某些类型为空白,我们想对其进行更正。

我正在尝试编写(如果可能)UPDATE语句,该语句将更新具有相同Order_Id的非空白记录类型的任何空白记录。一个约束是,如果有两个Order_Id相同但类型不同的记录,则什么也不会发生。

Order_ID   Item_ID    Type
1          1          'A'
1          2          ''   <-- Update to A, matches Rec 1, 1
2          1          'A'
2          2          'B'
2          3          ''   <-- Can't update because items 1 and 2 differ

可以合理地进行此类操作吗?到目前为止,我已经创建了一个自联接结果集(可以从中更新),但是我还没有弄清楚如何处理不同的项目。

SELECT
    a.Order_Id,
    a.Item_Id,
    a.[Type],
    b.[Type]
FROM Order_Item as a
CROSS APPLY 
(SELECT DISTINCT b.[Type] FROM Order_Item as b WHERE b.Order_Id = a.Order_ID AND b.[Type] != '') as b

3 个答案:

答案 0 :(得分:1)

这对CTE应该为您分配的Order_ID值仅分配了一个类型:

;With cte_Distinct_Type
As
(
    Select Distinct 
        oi.Order_ID
        , oi.Item_Type
    From dbo.Order_Item As oi
    Where oi.Item_Type <> ''
), cte_Singleton_Types
As
(
    Select
        cte.Order_ID
        , Count(cte.Order_ID) As Order_Count
    From cte_Distinct_Type As cte
    Group By 
        cte.Order_ID
    Having Count(cte.Order_ID) = 1
)

我将其余的留在您有能力的手中;)

答案 1 :(得分:1)

假设“更新”确实是指command=tweet,那么实际上您可以通过一个CTE和几个Window函数来实现此目的:

UPDATE

答案 2 :(得分:1)

一种非常相似的方法,但是我喜欢窗口功能。

DECLARE @mytable TABLE (
ORDER_ID INT,
Item_ID INT,
Type NCHAR(1)
)

INSERT INTO @mytable
(ORDER_ID, Item_ID, Type)
VALUES
(1,1,'A'), (1,2,''),(1,3,'A'),(2,1,'A'),(2,2,'B'),(2,3,'')


;WITH CTE AS (
    SELECT X.*, COUNT(*) OVER(PARTITION BY ORDER_ID) AS num_types
    FROM
    (
        SELECT DISTINCT ORDER_ID, Type
        FROM @mytable
        WHERE Type != ''
    ) AS X
)

UPDATE a
SET a.Type = CTE.Type
FROM @mytable a
INNER JOIN CTE
ON CTE.ORDER_ID = a.ORDER_ID
WHERE CTE.num_types = 1

SELECT * FROM @mytable