0

我有一个巨大的主表(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 行,将 Row2 链接到 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。

有更好的解决方案吗?

4

1 回答 1

0

这是交易的“一招”。

更新所有列,但如果没有为潜在的更新值提供值(空值)......忽略它并使用原始值......使用 CASE 语句。

您在原始帖子中的语言有点混乱。

我认为“字段”是指“列”.......(我不是在吹毛求疵,我试图区分列和“列中的值”。)

也许以下内容可以提供帮助。

这是一个通用的罗斯文示例

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
于 2013-05-09T17:55:37.780 回答