我偶然发现了一个令人烦恼的情况,即我的源查询结果具有重复的键且数据不同。不幸的是,我需要回填所有NULL。
我尝试使用MERGE
,但遇到关键错误。
MySQL(我无法转换)中的等效查询为:
请注意,我更改了所有字段和表名
INSERT INTO user_brief (name, high_score, colour)
SELECT
u.name,
h.high_score,
p.colour,
FROM foo_table AS f
LEFT JOIN users AS u ON f.user_id = u.id
LEFT JOIN high_scores AS h ON f.user_id = h.id
LEFT JOIN preferences AS p ON f.user_id = p.id
ON DUPLICATE KEY
UPDATE
name = COALESCE(user_brief.name, VALUES(name)),
high_score = COALESCE(user_brief.high_score, VALUES(high_score)),
colour = COALESCE(user_brief.colour, VALUES(colour));
选择查询结果
如果仅使用SELECT,您将获得以下结果:
name | high_score | color
---------------------------
foo | NULL | brown
foo | 40 | NULL
bar | 29 | blue
...
所需结果
name | high_score | color
---------------------------
foo | 40 | brown
bar | 29 | blue
...
如您所见,它已经变平了(不确定这是否是正确的术语),它为name
键控记录的每一列取了第一个非空值。
我尝试的MERGE
解决方案(但出现关键错误):
MERGE INTO user_brief AS target
USING (SELECT
u.name,
h.high_score,
p.colour,
FROM foo_table AS f
LEFT JOIN users AS u ON f.user_id = u.id
LEFT JOIN high_scores AS h ON f.user_id = h.id
LEFT JOIN preferences AS p ON f.user_id = p.id) AS source
ON target.name = source.name
WHEN MATCHED THEN
UPDATE SET
target.name = COALESCE(source.name, target.name),
target.high_score = COALESCE(source.high_score, target.high_score),
target.colour = COALESCE(source.colour, target.colour)
WHEN NOT MATCHED BY TARGET THEN
INSERT (name, high_score, colour)
VALUES (source.name, source.high_score, source.colour);
答案 0 :(得分:1)
您可以使用GROUP BY
来拼合源代码:
WITH source AS (
SELECT
u.name,
high_score = MIN(h.high_score),
colour = MIN(p.colour)
FROM foo_table AS f
LEFT JOIN users AS u ON f.user_id = u.id
LEFT JOIN high_scores AS h ON f.user_id = h.id
LEFT JOIN preferences AS p ON f.user_id = p.id
GROUP BY u.name
)
MERGE INTO user_brief AS target
USING source
ON target.name = source.name
WHEN MATCHED THEN
UPDATE SET
target.name = COALESCE(source.name, target.name),
target.high_score = COALESCE(source.high_score, target.high_score),
target.colour = COALESCE(source.colour, target.colour)
WHEN NOT MATCHED BY TARGET THEN
INSERT (name, high_score, colour)
VALUES (source.name, source.high_score, source.colour);