我有一个巨大的主表(1tb数据)和超过20列。我有0个或更多丢失数据字段的源数据。我必须通过匹配主表中的可用字段来填写缺少的数据。请考虑以下示例:
传入数据:
CREATE TABLE #t1 ( f3 VARCHAR(50), f1 INT, f2 INT )
INSERT INTO #t1
SELECT 'Row1',1, NULL
UNION ALL
SELECT 'Row2', 1, 2
主表:
CREATE TABLE #t2 ( f1 INT, f2 INT, f3 INT, f4 VARCHAR(255) )
INSERT INTO #t2
SELECT 1, 2, 3, 'A'
UNION ALL
SELECT 1, 2, 4, 'B'
UNION ALL
SELECT 1, 3, 3, 'C'
UNION ALL
SELECT 1, 3, 4, 'D'
UNION ALL
SELECT 2, 3, 4, 'E'
我希望输出将Row1链接到行A,B,C和D以及行2链接到行A和B.我可以通过以下方式实现此目的:
SELECT a.f3, b.*
FROM #t2 b
CROSS JOIN #t1 a
WHERE Patindex(Isnull(CONVERT(CHAR(1), a.f1), '_') + Isnull(CONVERT(CHAR(1), a.f2), '_')
, CONVERT(CHAR(1), b.f1) + CONVERT(CHAR(1), b.f2)) != 0
DROP TABLE #t1
DROP TABLE #t2
这不是一个非常可扩展的解决方案,因为当我有20个字段时,它将变成冗长而复杂的SQL。
有更好的解决方案吗?
答案 0 :(得分:0)
这是交易的“一招”。
更新所有列,但是如果没有为潜在更新值给出值(空值)....忽略它并使用原始值....使用CASE语句。
您原来帖子中的语言有点令人困惑。
我认为“字段”你的意思是“列”.......(我不是在挑剔,我试图区分列和“列中的值”。)< / p>
也许以下内容可以提供帮助。
这是一个通用的Northwind示例
Use Northwind
GO
IF OBJECT_ID('tempdb..#OrderDetailsHolder') IS NOT NULL
begin
drop table #OrderDetailsHolder
end
CREATE TABLE #OrderDetailsHolder
(
IdentityKey int not null identity (1001, 1),
[OrderID] int,
[ProductID] int,
[UnitPrice] money
)
INSERT INTO #OrderDetailsHolder ( OrderID, ProductID , UnitPrice )
Select top 10 OrderID, ProductID , UnitPrice from dbo.[Order Details] where UnitPrice IS NOT NULL
print 'Before massaged data look'
select * from #OrderDetailsHolder
Update #OrderDetailsHolder Set [UnitPrice] = null where IdentityKey < 1006
Update #OrderDetailsHolder Set [UnitPrice] = ([UnitPrice] * 1.333) where IdentityKey >= 1006
print 'After massaged data look'
select * from #OrderDetailsHolder
/*
Here is the magic (below query).
If [UnitPrice] is NULL in the "holder" temp table, then KEEP THE ORIGINAL value.
If the UnitPrice is NOT null in the temp table, update using the holder-temp table UnitPrice value.
*/
Update dbo.[Order Details]
Set [UnitPrice] = CASE
WHEN holder.[UnitPrice] IS NOT NULL then holder.UnitPrice
ELSE realTable.UnitPrice
END
FROM
#OrderDetailsHolder holder , dbo.[Order Details] realTable
Where
holder.OrderID = realTable.OrderID and holder.ProductID = realTable.ProductID
/* Now show the real table data, which should have 5 rows as having different UnitPrice values */
Select * from #OrderDetailsHolder holder join dbo.[Order Details] realTable
on holder.OrderID = realTable.OrderID and holder.ProductID = realTable.ProductID
IF OBJECT_ID('tempdb..#OrderDetailsHolder') IS NOT NULL
begin
drop table #OrderDetailsHolder
end