Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL标准是怎么说的;相依;更新中的条件句?_Sql_Standards - Fatal编程技术网

SQL标准是怎么说的;相依;更新中的条件句?

SQL标准是怎么说的;相依;更新中的条件句?,sql,standards,Sql,Standards,有谁能告诉我,根据标准,以下结果应该是什么(欢迎参考标准的正确部分) >从t1中选择*; +------+ |可乐| +------+ | 9 | | 8 | | 10 | +------+ >更新t1 设置col1=col1*2 其中col1从t1中选择*; +------+------+ |col1 | col2| +------+------+ | 9 | 1 | | 8 | 2 | | 10 | 2 | +------+------+ >

有谁能告诉我,根据标准,以下结果应该是什么(欢迎参考标准的正确部分)

>从t1中选择*;
+------+
|可乐|
+------+
|    9 |
|    8 |
|   10 |
+------+
>更新t1
设置col1=col1*2
其中col1从t1中选择*;
+------+------+
|col1 | col2|
+------+------+
|    9 |    1 |
|    8 |    2 |
|   10 |    2 |
+------+------+
>更新t1 p1
设置col1=col1*2

其中col1最后一行不会得到更新。
因为“select avg(col1)from t1”是一个子查询,它将首先运行,并将结果存储在临时表中,然后执行update语句。

关于第一个查询,子查询首先执行,因此平均值没有变化

关于第二个查询,您在
UPDATE
语句中使用了别名,但使用别名的方法不正确

UPDATE
语句中使用别名的正确标准方法是:

UPDATE p1
     set col1 = col1 * 2
from t1 p1
     where col1 <= (select avg(col1)
                     from t1
                     where col2=p1.col2);
更新p1
设置col1=col1*2
从t1到p1

据我所知,标准(SQL 2003-Foundation第14.11章)对此非常清楚:

在更新T的任何一行之前,对T的每一行进行有效评估

(强调矿山)


我对这句话的理解是,在更新任何行之前,都会对任何条件(无论是否相关)进行评估

这里首先执行子查询。所以平均值不会改变。@Shiplu谢谢。第二种情况如何,子查询不能预执行?@baruch-它可以预执行,因为单独的读取操作会标识要更新的行,并将行标识符存储在假脱机或类似文件中,然后在读取完成后从该假脱机读取更新。这就是我在SQLServer中所期望的计划。不过,我不确定我是否会费心钻研SQL标准来找到相关的代码。有两个相关概念是“所有一次性操作”和万圣节保护。SQL标准不允许对
UPDATE
语句使用
FROM
子句。所以你的例子不是“标准方式”。此外,在SQL标准中,表别名在
UPDATE
部分中定义:
UPDATE[[AS]]
。以上语法仅在我没有弄错@a_horse_和_no_name:Thank you的情况下对MySQL有效。它在MS-SQL Server上工作。我已经在MSSQL中测试了上述查询,但当我执行OP的第二个查询时,它抛出错误…检查SQL Server在数据交换中的行为:。。。一个不符合标准的流行(如果不是唯一的DBMS的话)是MySQL,与示例查询类似,可能会导致非标准结果。@ypercube:为什么我不感到惊讶?老实说,这是与标准最严重的偏差之一,如果不是最严重的话。即使是简单的
UPDATE t SET id=id+1
也是以串行方式完成的,而不是作为一个SET操作,这将导致PK冲突。@ypercube:也存在从自引用表中删除行的情况:在Oracle、PostgreSQL和其他表中可以正常工作,但在MySQL中则不行。顺便说一句:
id=id+1
仅适用于Postgres sincd 9.0和可延迟唯一约束
> select * from t1;
+------+------+
| col1 | col2 |
+------+------+
|    9 |    1 |
|    8 |    2 |
|   10 |    2 |
+------+------+
> update t1 p1
    set col1 = col1 * 2
    where col1 <= (select avg(col1)
                     from t1
                     where col2=p1.col2);
UPDATE p1
     set col1 = col1 * 2
from t1 p1
     where col1 <= (select avg(col1)
                     from t1
                     where col2=p1.col2);