使用FROM的SQL UPDATE查询

时间:2017-08-18 13:52:56

标签: sql database sql-update

在回答测试时,我遇到了以下问题,我无法解决:

给出下表Z和查询:

Table Z:
| Value |
---------
|   1   |
|   2   |
|   3   |
|   4   |
---------

查询:

UPDATE Z 
    SET VALUE = Y.VALUE + 1
    FROM Z AS Y 
    WHERE Y.VALUE = Z.VALUE + 1;

SELECT SUM(VALUE) FROM Z;

该问题询问此查询执行的结果。问题没有提到特定的SQL语言。

CORRECT答案是16。

我不知道这个查询如何实现这个结果。我甚至无法在真实环境中执行此查询,它抱怨“FROM”附近有一些语法错误。

1 - 你们知道这个查询是如何工作的吗? 2 - 我如何继续执行此查询?

P.S。我很难在UPDATE查询中找到有关FROM子句的一些信息。

3 个答案:

答案 0 :(得分:2)

代码可以使用的一个数据库是Postgres。根据{{​​3}},这确实是答案。

原因应该是因为您为每个匹配的Z值添加“2”:z = y.value + 1 = z.value + 1 + 1 - 但第四个值不匹配。 Postgres生成以下内容:

    value
1   4
2   3
3   4
4   5

这是相同数据的顺序。

通过类似的陈述,RexTester做了正确的事:

UPDATE Z 
    SET val = Y.val + 1
    FROM Z, Z AS Y 
    WHERE Y.val = Z.val + 1;

(我在FROM子句中使用可怕的逗号来保持两个语句尽可能相似。)

它返回:

    val
1   3
2   4
3   5
4   4

两个结果集是相同的,它们的顺序不同。

答案 1 :(得分:2)

我希望这可以帮助(在MSSQL上制作): 第一个SELECT将显示更新将使用的原始值。

我在事务/回滚中进行了UPDATE,因此它不会更改表。如果要更改数据表,可以删除BEGIN TRAN和ROLLBACK TRAN。

CREATE TABLE TZ (VALUE INT)
    INSERT INTO TZ VALUES (1),(2),(3),(4)

    SELECT Z.VALUE AS Z_VALUE, Y.VALUE AS Y_VALUE
     FROM TZ Z 
     INNER JOIN TZ Y  ON Y.VALUE=Z.VALUE +1
     ;

    BEGIN TRAN
    UPDATE Z SET VALUE=Y.VALUE+1
    FROM TZ Z 
    INNER JOIN TZ Y ON Y.VALUE=Z.VALUE +1
    ;
    SELECT * FROM TZ;
    SElECT SUM(VALUE) AS TOT FROM TZ;
    ROLLBACK TRAN

首先输出SELECT:

Z_VALUE, Y_VALUE
1      , 2   
2      , 3
3      , 4

UPDATE后输出SELECT:

VALUE
3
4
5
4

所以,SUM实际上是16

答案 2 :(得分:1)

如果这样做 - 并且我不希望它出现在每个数据库上 - 这可能有助于说明发生了什么。 Y只是Z的别名。此表表示更新期间表的连接和最终结果:

template<class CB, size_t... Is> void unroll_loop_impl(std::index_sequence<Is...> {}, CB&& cb) {
    void* aux[] = {(cb(Is), nullptr)...};
    (void)aux;
}


template<size_t N, class CB> void unroll_loop(CB&& cb) {
     using index_seqeunce_t = std::make_index_sequence<N>;

     unroll_loop_impl(std::move(cb), index_sequence_t{});
}