SQL如何使用join进行update操作?

4
我有两个表格,一个是简单的字符串/ID查找表:
StrTable:
str_key String 0 'a' 1 'b'
其中字符串是唯一的。另一个表格更为复杂,包括共享的string_id:
ValTable:
str_key other_key val 0 0 1.234 0 1 1.567 1 0 1.890
现在,我想要对ValTable进行更新,使用一个字符串来查找StrTable获取str_key。简单的更新方式如下:
UPDATE ValTable SET val = 2.124 WHERE str_key = 0 AND other_key = 1 LIMIT 1
IF @@ROWCOUNT=0 INSERT INTO ValTable VALUES (0,1,2.124);

那么我如何修改这个查询,以便使用某个字符串'a'查找str_key?我猜我需要一个join,但我从未在update中使用过join。或者我只需在where子句中添加更多条件吗?


你没有表的DDL,但假设str_key和other_key组成了ValTable的主键,你为什么要加上"LIMIT 1"呢?即使它不是主键,使用LIMIT在这里似乎有些奇怪。 - Tom H
我不确定在没有限制条件的情况下是否会导致整个表的扫描,但我想它足够聪明,知道复合键是the键,只影响那一行。 - Phil H
2个回答

14

这是你需要的语法:

UPDATE  v
SET     val = 2.124
FROM    ValTable v
        INNER JOIN
                StringTable s
                ON v.str_key = s.str_key
WHERE   s.String = 'a'
AND     v.other_key = 1

IF @@ROWCOUNT = 0
BEGIN

        INSERT
        INTO    ValTable
        SELECT  str_key, 1, 2.124
        FROM    StringTable
        WHERE   String = 'a'

END

我该如何修改第二行?我可以这样做吗: IF @@ROWCOUNT=0 INSERT INTO v VALUES (v.str_key, 1, 2.124) 还是我需要使用另一个连接重新确定v.str_key? - Phil H

1

David M的示例是有效且可行的。根据您的表的大小,您可能希望避免执行"Blind Updates",因为这可能会在非常大的表上导致性能问题。请注意IF EXISTS()中的表提示。

IF EXISTS(
        SELECT 
            * 
        FROM 
            ValTable v WITH(NOLOCK)
            INNER JOIN StringTable s WITH(NOLOCK) ON v.str_key = s.str_key 
        WHERE 
            s.String = 'a' 
        AND v.other_key = 1
    )
BEGIN
    UPDATE  
        v
    SET     
        val = 2.124
    FROM    
        ValTable v
        INNER JOIN StringTable s ON v.str_key = s.str_key
    WHERE   
        s.String = 'a'
    AND v.other_key = 1
END
ELSE
BEGIN
    INSERT INTO ValTable
        --(You should define your columns here, You didn't provide a sample schema so I don't know what your columns are.)
        --(Col1,COl2,COl3,etc...)
    SELECT  
        str_key, 1, 2.124
    FROM    
        StringTable
    WHERE   
        String = 'a'
END

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接