我尝试使用TableB中相应的ADDR_ID更新下面TableA中的多个列。这是一个片段,实际上我在TableA中有30个位置,在TableB中有30个EXT_ID,因此执行Update语句会花费一些时间。问题是TableA中的30个位置中的任何一个都可能存在于TableB中的30个EXT_ID中的任何一个中。
例如,在TableA中,ID = 44231,位置A35555可能在EXT_ID_27中的TableB中匹配,所以我真的希望有人可以提出比900更新语句更好的替代方案......
下面的SQL小提琴
表A
+---------+-----------+-------------------------------------+----------------+-------------------------------------+
| ID | LOC_1 | LOC_1_ADDR_ID | LOC_2 | LOC_2_ADDR_ID |
+---------+-----------+-------------------------------------|----------------+-------------------------------------|
| 44231 | A35555 | Trying to Populate Should Be Z76543 | B68754 | Trying to Populate should be Z45545 |
| 87563 | A36666 | Trying to Populate Should Be Z83465 | Q23548 | Trying to Populate should be Z89224 |
| 85387 | R14587 | Trying to Populate Should be Z66371 | A35555 | Trying to Populate should be Z93827 |
+---------+-----------+-------------------------------------+----------------+-------------------------------------|
表B(EXT_ID对于每个REC_ID是唯一的,但是多个REC_ID可以具有相同的EXT_ID)
+---------+-----------+-------------+-----------+-----------+
| REC_ID | ADDR_ID_1 | EXT_ID_1 | ADDR_ID_2 | EXT_ID_2 | (28 more external ID columns)
+---------+-----------+-------------+-----------+-----------+
| 44231 | Z76543 | A35555 | Z45545 | B68754 |
| 87563 | Z83465 | A36666 | Z89224 | Q23548 |
| 85387 | Z93827 | A35555 | Z66371 | R14587 |
+---------+-----------+-------------+-----------|-----------+
http://sqlfiddle.com/#!3/02d5c/5/0
感谢您的任何建议!
答案 0 :(得分:1)
如果表B中的30列“对”实际上是具有相同含义的重复数据(位置键/地址对),则设计应该只有2列且数据更多。实际表不遵循此设计,但您查询的数据可以。
SELECT EXT_ID_1 AS EXT_ID, ADDR_ID_1 AS ADDR_ID FROM TableB UNION ALL
SELECT EXT_ID_2 AS EXT_ID, ADDR_ID_2 AS ADDR_ID FROM TableB UNION ALL
SELECT EXT_ID_3 AS EXT_ID, ADDR_ID_3 AS ADDR_ID FROM TableB UNION ALL
...
SELECT EXT_ID_30 AS EXT_ID, ADDR_ID_30 AS ADDR_ID FROM TableB
这会为您提供两列数据,这样可以更轻松地编写查询。将其转储到临时表(或表变量)中,您可以继续使用30个UPDATE语句,优于900.
或者,您可以在一个声明中尝试:
WITH (
SELECT EXT_ID_1 AS EXT_ID, ADDR_ID_1 AS ADDR_ID FROM TableB UNION ALL
SELECT EXT_ID_2 AS EXT_ID, ADDR_ID_2 AS ADDR_ID FROM TableB UNION ALL
SELECT EXT_ID_3 AS EXT_ID, ADDR_ID_3 AS ADDR_ID FROM TableB UNION ALL
...
SELECT EXT_ID_30 AS EXT_ID, ADDR_ID_30 AS ADDR_ID FROM TableB
) AS SimplifiedTableB
UPDATE TableA
SET
LOC_1_ADDR_ID = COALESCE(TableB1.ADDR_ID, LOC_1_ADDR_ID),
LOC_2_ADDR_ID = COALESCE(TableB2.ADDR_ID, LOC_2_ADDR_ID),
LOC_3_ADDR_ID = COALESCE(TableB3.ADDR_ID, LOC_3_ADDR_ID),
...
LOC_30_ADDR_ID = COALESCE(TableB30.ADDR_ID, LOC_30_ADDR_ID)
FROM
TableA
LEFT JOIN SimplifiedTableB AS TableB1 ON TableA.LOC1 = TableB1.EXT_ID
LEFT JOIN SimplifiedTableB AS TableB2 ON TableA.LOC2 = TableB2.EXT_ID
LEFT JOIN SimplifiedTableB AS TableB3 ON TableA.LOC3 = TableB3.EXT_ID
...
LEFT JOIN SimplifiedTableB AS TableB30 ON TableA.LOC30 = TableB30.EXT_ID
但是,出于正确性和性能原因,我建议事先对此进行测试。
答案 1 :(得分:1)
注意到这已得到解答,因为无论如何我正在研究这个问题,这里有一个替代方案.. 从Unpivot multi columns
收到的一些信息select tblB.REC_ID, tblB.ADDR_ID, tblB.EXT_ID
into #tempTableB
from
(
select REC_ID, ADDR_ID, EXT_ID
from TableB
Unpivot
(
ADDR_ID for ADDR_IDS in (ADDR_ID_1, ADDR_ID_2)
) as UnPvtADDR
Unpivot
(
EXT_ID for EXT_IDS in (EXT_ID_1, EXT_ID_2)
) as UnPvtEXT
where RIGHT(ADDR_IDS, 1) = RIGHT(EXT_IDS, 1)
) tblB
-- [depend on number of records in #tmepTableB]
-- Create Index on #tempTablB.REC_ID to improve performance if required
update tblA
set LOC_1_ADDR_ID = (select ADDR_ID from #tempTableB where REC_ID = tblA.ID and EXT_ID = tblA.LOC_1)
, LOC_2_ADDR_ID = (select ADDR_ID from #tempTableB where REC_ID = tblA.ID and EXT_ID = tblA.LOC_2)
-- .. and the rest of the columns
from TableA tblA
inner join
#tempTableB tblB
on tblA.ID = tblB.REC_ID
where tblA.ID = tblB.REC_ID
select * from TableA