如何在子查询中使用主查询中的信息进行更新?

问题描述 投票:0回答:3

我在多语言网站上处理文章,用户可以更新内容。我使用 MySQL 数据库。

articles
id

article_contents
:
id
article_id
(FK)
content
lang
version

如果新内容还是草稿,

version
就是
null
。一旦草稿经过主持人验证,它就会成为最终版本,并针对给定的
version
和给定的
article_id
采用下一个可用的
lang

UPDATE article_contents
SET version=(
    SELECT MAX(version)
    FROM article_contents
    WHERE article_id=SAME_AS_THE_ONE_IN_THE_MAIN_QUERY
    AND lang=SAME_AS_THE_ONE_IN_THE_MAIN_QUERY
) + 1
WHERE id=:id; 

我可以用什么来代替

SAME_AS_THE_ONE_IN_THE_MAIN_QUERY
,或者有没有更干净的方法来做到这一点?

sql mysql subquery
3个回答
1
投票

使用相关子查询,即让它引用更新表:

update article_contents ac
set version = coalesce((select max(version)
                        from article_contents
                        where article_id = ac.article_id
                          and lang = ac.lang), 0) + 1
where id = :id;

演示:https://dbfiddle.uk/IkH8jGmy


0
投票

如果您可以使用变量,请尝试像这样的 smt (T-SQL):

begin
 declare @v_test NVARCHAR(MAX)
 declare @v_lang NVARCHAR(MAX)

-- IDK where id/lang comes from, so I'm just setting them like this
 set @v_test = 'VC000033'
 set @v_lang = 'eng'

    update [your table]
    set [your column] = (
        select max([your column]) + 1
        from [your table]
        where No_ = @v_test
        and lang = @v_lang)
    where No_ = @v_test
end

根据您正在执行的操作, 这可能不是性能方面最好的解决方案。 为此,您可能想尝试CTE


0
投票

您想将当前已验证文章的版本更新为按升序排列的下一个版本吗?

我认为你不需要匹配 id 和语言,为什么你需要匹配,因为当时你的版本为空。相反,只需获取总体最高版本并添加 1。

UPDATE article_contents
SET version=(
    SELECT TOP 1 version
    FROM article_contents
    ORDER BY 1 desc
) + 1
WHERE id=@id; 

我错了,您想要一篇特定文章的版本。谢谢 jarlh 指出。

UPDATE ac  
   SET version=(
        SELECT TOP 1 ISNULL(version,0)
        FROM article_contents ac2
        WHERE ac2.article_id  = ac.article_id 
            AND ac2.lang = ac.lang
        ORDER BY 1 desc
    ) + 1
    FROM article_contents ac
    WHERE id=@id; 
© www.soinside.com 2019 - 2024. All rights reserved.