【问题标题】:Linking on 0 or more missing data fields链接 0 个或多个缺失数据字段
【发布时间】:2013-05-10 01:55:37
【问题描述】:

我有一个巨大的主表(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' 

我希望输出将第 1 行链接到 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。

有没有更好的解决方案?

【问题讨论】:

  • 那么,如果输入具有该列的值,您希望在相应列上匹配(“=”),但如果该列为 NULL,则跳过该列(即,将其视为通配符)?对吗?

标签: sql-server tsql join jointable


【解决方案1】:

这是交易的“一招”。

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

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

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

也许以下内容会有所帮助。

这是一个通用的 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

【讨论】:

    猜你喜欢
    • 2013-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多