合并到使用源行的目标列?
问题描述:
我有一些结构良好的数据,如下所示:
I have some nicely-structured data that looks like this:
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');
可悲的是,目标结构不是很好,看起来更像这样:
Sadly, the target structure is no so nice, and looks more like this:
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
:
I can write a SQL-92 UPDATE
like this:
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'
);
...但是重复的代码使我感到困扰.
...but the repeated code bothers me.
我认为,这是简化使用MERGE
的一个很好的候选人,但我无法提出任何合理的建议.
A good canidate for simplifying using MERGE
, I thought, but I can't come up with anything reasonable.
任何想法如何将MERGE
与此数据一起使用. (注意:谢谢,我想避免使用专有的UPDATE..FROM syntax
.)
Any ideas how to use MERGE
with this data. (Note: I want to avoid the proprietary UPDATE..FROM syntax
, thanks.)
答
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 ;