如何根据给定表中的层次结构删除列中的值?

时间:2015-08-10 21:30:22

标签: sql tsql sql-server-2012

在表1中,我有客户ID和客户ID已购买的物品清单。

表1

Customer ID | Item Code
------------------------
 1000       |  10
 1000       |  20 
 1000       |  30
 1000       |  40
 2000       |  10
 2000       |  60
 2000       |  90
 2000       |  100
------------------------

在另一个表中,我有一个Hierarchy,如下所示

表2

This has precedence | Over This
---------------------------------
      30            |     10
      20            |     40
      60            |     90
      100           |     60
---------------------------------

我想在Table 1中添加一个结果列,例如,对于客户1000,根据表2消除10乘30和40乘20。

案例1:10应仅由客户1000替换为30,因为客户1000的“项目代码”列中存在30,而不是客户2000。

案例2:对于Customer 2000,60应替换为90,并且两行应替换为90.

理想情况下,最终结果应如下 -

  

客户ID |商品代码|最终守则

 1000       |  10   | 30
 1000       |  20   | 20
 1000       |  30   | 30
 1000       |  40   | 20
 2000       |  10   | 10 (This is not replaced!)
 2000       |  60   | 100
 2000       |  90   | 100
 2000       |  100  | 100

3 个答案:

答案 0 :(得分:0)

进行更新,假设这些是您真正的列名:

ALTER TABLE Table1
ADD result int

UPDATE a
SET result = [Item Code] - [This has precedence]
from Table1 a
inner join Table2 b
on a.[Item Code] = b.[Over this]

答案 1 :(得分:0)

update2:基于问题更新

select a.*,ISNULL(d.[This has precedence],a.ItemCode) as [Final Code]
 from table1 a left join 
 (select b.[This has precedence],b.[over this],c.customerID from 
 (select ISNULL(q.[This has precedence],p.[This has precedence]) as [This has precedence],p.[Over This] from table2 p left join table2 q
on p.[This has precedence]=q.[Over This])
  b 
 inner join  table1 c on C.ItemCode=b.[This has precedence]) d
  on a.ItemCode=d.[Over This]
 and d.customerID=a.CustomerID

更新:根据提问者最近的评论

  

我错过了在问题中添加一个条款。 10应该被替换   30仅当列项目代码中存在30时   客户1000。

结果如

Customer ID | Result
------------------
 1000       | 30
-------------------------
 1000       | 20 
--------------------------
 1000       | 20
--------------------------
 2000       |  10 

更新的查询就像:

select DISTINCT a.CustomerID,ISNULL(d.[This has precedence],a.ItemCode) as result
 from table1 a left join 
 (select b.[This has precedence],b.[over this],c.customerID from table2 b 
 inner join  table1 c on C.ItemCode=b.[This has precedence]) d
  on a.ItemCode=d.[Over This]
 and d.customerID=a.CustomerID

之类的结果
Customer ID | Item Code| Result
------------------
 1000       |  10   | 30
-------------------------
 1000       |  20   |NULL 
--------------------------
 1000       |  30   |NULL
--------------------------
1000        |  40   |20
--------------------------
 2000       |  10   | NULL

使用以下查询:

select a.*,d.[This has precedence] as result
 from table1 a left join 
 (select b.[This has precedence],b.[over this],c.customerID from table2 b 
 inner join  table1 c on C.ItemCode=b.[This has precedence]) d
  on a.ItemCode=d.[Over This]
 and d.customerID=a.CustomerID
  

如果你想要这样的结果

Customer ID | Item Code| Result
------------------
 1000       |  10   | 30
-------------------------
 1000       |  20   |NULL 
--------------------------
 1000       |  30   |NULL
--------------------------
1000        |  40   |20
--------------------------
 2000       |  10   | 30
     

然后下面的查询将起作用

select a.*,b.[This has precedence] as result
 from table1 a left join table2 b on a.ItemCode=b.[Over This]
     

如果要替换行并获取不同的值

Customer ID | Item Code
------------------
 1000       |  30  
-------------------
 1000       |  20  
-------------------
 2000       |  30
     

使用以下查询

update a
set a.ItemCode=b.[This has precedence] 
 from table1 a left join table2 b on a.ItemCode=b.[Over This]
     

接着是

select * from table1
     

如果您不想更新table1并只是获取上述输出   然后

select DISTINCT a.CustomerID,b.[This has precedence] as result
 from table1 a left join table2 b on a.ItemCode=b.[Over This]

答案 2 :(得分:0)

在OP更新后更新查询并显示递归。

如果您想在表1中添加列以显示优先级数据。在这里你如何实现它。

   ALTER TABLE Table1
     ADD Result int
   GO

       ;WITH CTE([This has Precedence], [Over This]) 
       AS
       (
       --First find the top level members
       --These are the items which does't have any precedence
       SELECT T2A.[This has Precedence], T2A.[Over This] FROM dbo.Table2 T2A
       LEFT JOIN dbo.Table2 T2B
       ON T2A.[This has Precedence] = T2B.[Over This]
       WHERE T2B.[Over This] IS NULL

       UNION ALL
       --Now call the lower level members and join with the CTE
       SELECT CTE.[This has Precedence],  T2.[OVER THIS] 
       FROM dbo.Table2 T2
       INNER JOIN CTE ON T2.[This has Precedence] = CTE.[Over This]
       )

  --Now use the recursive CTE to find the correct precedence member.
   UPDATE T1
   SET Result = ISNULL(T1x.[Item Code], T1.[Item Code])
   FROM Table1 T1
    LEFT JOIN CTE T2
            ON T1.[Item Code] = T2.[Over This]
    LEFT JOIN Table1 T1x
            ON T2.[This has Precedence] = T1x.[Item Code]
           AND T1.CID = T1x.CID
  GO