Что стандарт SQL говорит об «зависимых» условных выражениях в UPDATE? - PullRequest
6 голосов
/ 01 апреля 2012

Может кто-нибудь сказать мне, каков должен быть результат в соответствии со стандартом (ссылка на правильную часть стандарта приветствуется)

> select * from t1;
+------+
| col1 |
+------+
|    9 |
|    8 |
|   10 |
+------+
> update t1
    set col1 = col1 * 2
    where col1 <= (select avg(col1) from t1);

Дело в том, обновляется ли последняя строка, поскольку, если строки обновляются по порядку, а среднее значение пересчитывается для каждой строки, оно будет удовлетворять условию или не обновляется, поскольку любые данные, измененные этим оператором будет доступен для чтения только после выполнения всего оператора?

EDIT А как насчет этого дела?

> 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);

Ответы [ 3 ]

4 голосов
/ 01 апреля 2012

По первому запросу, subquery выполняется первым, поэтому в среднем нет изменений ...

По второму запросу вы используете псевдоним в операторе UPDATE, но вы используете псевдоним внеправильный подход.

Правильный и стандартный способ использования псевдонима в выражении UPDATE:

UPDATE p1
     set col1 = col1 * 2
from t1 p1
     where col1 <= (select avg(col1)
                     from t1
                     where col2=p1.col2);
4 голосов
/ 01 апреля 2012

Насколько я могу судить, стандарт (глава 14.11, SQL 2003 - Foundation) достаточно ясен по этому поводу:

Эффективно оценивается для каждой строки T до обновляется любая строка T

(акцент мой)

Мое понимание этого предложения состоит в том, что любое условие (независимо от того, связано ли оно с этим или нет) оценивается до обновления какой-либо строки.

2 голосов
/ 01 апреля 2012

Последняя строка не будет обновлена.поскольку «select avg (col1) from t1» является подзапросом, и он сначала будет выполняться, и результат будет сохранен во временной таблице, затем будет выполнен оператор обновления.

...