Sql 是否使用源行合并到目标列?

Sql 是否使用源行合并到目标列?,sql,tsql,sql-server-2008,merge,standards-compliance,Sql,Tsql,Sql Server 2008,Merge,Standards Compliance,我有一些结构良好的数据,如下所示: 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)

我有一些结构良好的数据,如下所示:

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);
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'
                     );
遗憾的是,目标结构不太好,看起来更像这样:

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);
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'
                     );
我可以像这样编写SQL-92
更新

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);
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'
                     );
…但重复的代码让我很烦恼

我想,这是一个简化使用
合并
的好方法,但我想不出任何合理的方法


如何使用
合并
此数据的任何想法。(注意:我想避免专有的
UPDATE..FROM syntax
,谢谢。)

AFAIK,MERGE是SQL:2003,这真的更好吗?@marc_s:我明白为什么你可能认为它是EAV,但实际上不是。请参阅Wikipedia关于第一范式的文章():“目标”结构类似于副标题“跨列重复组”(即1NF违规)下显示的
Customer
表。“源”结构更像是“符合1NF的设计”子目下显示的
客户电话表
表。@onedaywhen-我不同意。我对1NF冲突的经验法则是,您可以交换列值,并且仍然得到语义相同的结果。如果您可以交换
tel1
tel2
,并且语义保持不变,那么这显然不在1NF中。c、 f.@Martin:你对1NF有自己的定义?!嗯,呃。。。我想这一定会让你感到安慰:)@Martin:不过说真的。我认识到我快速起草的数据存在缺陷,例如“头发颜色”与“眼睛颜色”不属于同一领域。。。谁有金色的眼睛?!:)