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:不过说真的。我认识到我快速起草的数据存在缺陷,例如“头发颜色”与“眼睛颜色”不属于同一领域。。。谁有金色的眼睛?!:)