0

巨大なマスター テーブル (1 TB のデータ) と 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 を Row A、B、C、D にリンクし、Row2 を Row 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

ここにトレードの「ワントリック」があります。

すべての列を更新しますが、潜在的な更新値に値 (null 値) が指定されていない場合は....無視して元の値を使用します....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-09T17:55:37.780 に答える