如果匹配已经存在,如何将行号附加到行插入?
Posted
技术标签:
【中文标题】如果匹配已经存在,如何将行号附加到行插入?【英文标题】:How can I append on a row number on to a row insertion if a match already exists? 【发布时间】:2018-08-29 14:46:15 【问题描述】:我有一个包含电子邮件的用户表,例如:
johnsmith@gmail.com
我正在尝试使用可读条目批量更新用户的推荐代码。
我会将此代码设置到他们电子邮件的第一部分(@
符号之前),最多 12 个字符。
如果这些匹配项不止一个,例如:
johnsmith@gmail.com
和 johnsmith@aol.com
,那么第二个将在末尾附加一个数字增量。
这应该导致推荐代码为:
johnsmith
和 johnsmith1
等
现在,即使只有两个,我得到:
johnsmith1
和 johnsmith2
。
理想情况下,如果只有一个条目,则不应附加数字。
我该怎么做?
这是我目前拥有的:
UPDATE auth.user_referral_codes
SET referral_code = CONCAT((
SELECT LEFT(LEFT(email, STRPOS(email, '@') - 1), 12)
FROM auth.users
WHERE id = auth.user_referral_codes.user_id
) , (
SELECT row_number FROM (
SELECT row_number()
OVER (
PARTITION BY (SELECT LEFT(LEFT(email, STRPOS(email, '@') - 1), 12))
)
FROM auth.users
WHERE id = auth.user_referral_codes.user_id
) as row_number_subquery
));
【问题讨论】:
【参考方案1】:你的代码看起来很复杂:
update auth.user_referral_codes urc
set referral_code = (left(left(email, strpos(email, '@') - 1), 12) ||
(case when seqnum > 1 then seqnum::text else '' end)
)
from (select u.*,
row_number() over (partition by left(left(email, strpo(email, '@') - 1), 12) order by user_id) as seqnum
from users u
) u
where urc.user_id = u.id;
Postgres 在UPDATE
s 中支持FROM
子句。挺好用的。
【讨论】:
这看起来是一个很酷的解决方案。现在我要回来了:error: missing FROM-clause entry for table "u"
【参考方案2】:
稍微调整一下 Gordon Linoff 的回答,就可以了:
UPDATE auth.user_referral_codes urc
SET referral_code = (
LEFT(LEFT(email, strpos(email, '@') - 1), 12)
|| (CASE WHEN seqnum > 1 THEN (seqnum-1)::TEXT ELSE '' END)
)
FROM (
SELECT
auth.users.*,
row_number() OVER (
PARTITION BY LEFT(LEFT(email, strpos(email, '@') - 1), 12)
ORDER BY id
) AS seqnum
FROM auth.users
) AS u
WHERE urc.user_id = u.id;
【讨论】:
以上是关于如果匹配已经存在,如何将行号附加到行插入?的主要内容,如果未能解决你的问题,请参考以下文章
JAVA中,向MYSQL插入多条数据,如何判断如果某记录已经存在就不插入
如果 ETag 不匹配,如何使用 ETag 在插入时抛出异常(除非它是 *)