2010-12-02 17 views
-1

我有一些很好的結構化數據,看起來像這樣:MERGE將使用源行定位列嗎?

CREATE TABLE SourceBodyPartColors 
(
person_ID INTEGER NOT NULL, 
body_part_name VARCHAR(5) NOT NULL 
    CHECK (body_part_name IN ('hair', 'eye', 'teeth')), 
color VARCHAR(20) NOT NULL, 
UNIQUE (color, body_part_name, person_ID) 
); 

INSERT INTO SourceBodyPartColors (person_ID, body_part_name, color) 
    VALUES (1, 'eye', 'blue'), 
      (1, 'hair', 'blond'), 
      (1, 'teeth', 'white'), 
      (2, 'hair', 'white'), 
      (2, 'teeth', 'yellow'), 
      (3, 'hair', 'red'); 

可悲的是,靶結構是不那麼好,而且看起來更像是這樣的:

CREATE TABLE TargetBodyPartColors 
(
person_ID INTEGER NOT NULL UNIQUE, 
eye_color VARCHAR(20), 
hair_color VARCHAR(20), 
teeth_color VARCHAR(20) 
); 

INSERT INTO TargetBodyPartColors (person_ID) 
    VALUES (1), (2), (3); 

我可以寫一個SQL- 92 UPDATE是這樣的:

UPDATE TargetBodyPartColors 
    SET eye_color = (
        SELECT S1.color 
         FROM SourceBodyPartColors AS S1 
        WHERE S1.person_ID 
           = TargetBodyPartColors.person_ID 
          AND S1.body_part_name = 'eye' 
        ), 
     hair_color = (
        SELECT S1.color 
         FROM SourceBodyPartColors AS S1 
         WHERE S1.person_ID 
           = TargetBodyPartColors.person_ID 
          AND S1.body_part_name = 'hair' 
        ), 
     teeth_color = (
         SELECT S1.color 
         FROM SourceBodyPartColors AS S1 
         WHERE S1.person_ID 
           = TargetBodyPartColors.person_ID 
          AND S1.body_part_name = 'teeth' 
        ); 

......但重複的代碼困擾我。

簡化使用MERGE,我想,但我不能拿出任何合理的東西簡化使用一個很好的canidate。

任何想法如何使用MERGE這個數據。 (注意:我想避免專有的UPDATE..FROM syntax,謝謝。)

+2

你是否開心使用`PIVOT`? – 2010-12-02 15:29:13

回答

6
WITH Pivoted AS 
(
    SELECT person_ID, eye, hair, teeth 
    FROM SourceBodyPartColors 
    PIVOT 
    (
    MAX (color) FOR body_part_name IN ([eye], [hair], [teeth]) 
    ) AS pvt 
) 
MERGE TargetBodyPartColors AS target 
USING Pivoted AS source 
ON (target.person_ID = source.person_ID) 
WHEN MATCHED THEN 
UPDATE SET eye_color = source.eye, 
      hair_color = source.hair, 
      teeth_color = source.teeth ;