Нужно, чтобы поле ONTOP стало равно '1' у элемента с ID=36 и у всех элементов таблицы с таким же полем DOCNAME.

Вроде не очень сложно, но не получается...
Код
UPDATE `DOCUMENTS` SET `ONTOP` = 1 WHERE `ID` = '36' AND `DOCNAME` = (SELECT `DOCNAME` FROM `DOCUMENTS` WHERE `ID` = '36')
Спасибо!
Спустя 19 минут, 14 секунд (31.07.2008 - 14:55) jetistyum написал(а):
Цитата(QuadMan @ 31.7.2008, 14:36) [snapback]44911[/snapback]
Помогите, пожалуйста составить правильный UPDATE.
Нужно, чтобы поле ONTOP стало равно '1' у элемента с ID=36 и у всех элементов таблицы с таким же полем DOCNAME.
Вроде не очень сложно, но не получается...
Спасибо!
Нужно, чтобы поле ONTOP стало равно '1' у элемента с ID=36 и у всех элементов таблицы с таким же полем DOCNAME.

Вроде не очень сложно, но не получается...
Код
UPDATE `DOCUMENTS` SET `ONTOP` = 1 WHERE `ID` = '36' AND `DOCNAME` = (SELECT `DOCNAME` FROM `DOCUMENTS` WHERE `ID` = '36')
Спасибо!
UPDATE
`DOCUMENTS`
SET
`ONTOP` = 1
WHERE
`ID` = '36' OR
`DOCNAME` = (SELECT `DOCNAME` FROM `DOCUMENTS` WHERE `ID` = '36')
Вот вроде как-то так !

Спустя 2 минуты, 23 секунды (31.07.2008 - 14:58) jetistyum написал(а):
Цитата(jetistyum @ 31.7.2008, 14:55) [snapback]44913[/snapback]
Цитата(QuadMan @ 31.7.2008, 14:36) [snapback]44911[/snapback]
Помогите, пожалуйста составить правильный UPDATE.
Нужно, чтобы поле ONTOP стало равно '1' у элемента с ID=36 и у всех элементов таблицы с таким же полем DOCNAME.
Вроде не очень сложно, но не получается...
Спасибо!
Нужно, чтобы поле ONTOP стало равно '1' у элемента с ID=36 и у всех элементов таблицы с таким же полем DOCNAME.

Вроде не очень сложно, но не получается...
Код
UPDATE `DOCUMENTS` SET `ONTOP` = 1 WHERE `ID` = '36' AND `DOCNAME` = (SELECT `DOCNAME` FROM `DOCUMENTS` WHERE `ID` = '36')
Спасибо!
UPDATE
`DOCUMENTS`
SET
`ONTOP` = 1
WHERE
`ID` = '36' OR
`DOCNAME` = (SELECT `DOCNAME` FROM `DOCUMENTS` WHERE `ID` = '36')
Вот вроде как-то так !

а вообще, лучше даже так
UPDATE
`DOCUMENTS`
SET
`ONTOP` = 1
WHERE
`DOCNAME` = (SELECT `DOCNAME` FROM `DOCUMENTS` WHERE `ID` = '36')
ведь и ID =36 тоже попадёт под это правило

Спустя 1 минута (31.07.2008 - 14:59) QuadMan написал(а):
Цитата(jetistyum @ 31.7.2008, 11:55) [snapback]44913[/snapback]
UPDATE
`DOCUMENTS`
SET
`ONTOP` = 1
WHERE
`ID` = '36' OR
`DOCNAME` = (SELECT `DOCNAME` FROM `DOCUMENTS` WHERE `ID` = '36')
Вот вроде как-то так !
`DOCUMENTS`
SET
`ONTOP` = 1
WHERE
`ID` = '36' OR
`DOCNAME` = (SELECT `DOCNAME` FROM `DOCUMENTS` WHERE `ID` = '36')
Вот вроде как-то так !

SQL на это ругается - #1093 - You can't specify target table 'DOCUMENTS' for update in FROM clause
мне кажется, тут дело в синтаксисе запроса UPDATE... как-то по-другому его описать нужно...
Спустя 3 секунды (31.07.2008 - 14:59) jetistyum написал(а):
Цитата(jetistyum @ 31.7.2008, 14:55) [snapback]44913[/snapback]
Цитата(QuadMan @ 31.7.2008, 14:36) [snapback]44911[/snapback]
Помогите, пожалуйста составить правильный UPDATE.
Нужно, чтобы поле ONTOP стало равно '1' у элемента с ID=36 и у всех элементов таблицы с таким же полем DOCNAME.
Вроде не очень сложно, но не получается...
Спасибо!
Нужно, чтобы поле ONTOP стало равно '1' у элемента с ID=36 и у всех элементов таблицы с таким же полем DOCNAME.

Вроде не очень сложно, но не получается...
Код
UPDATE `DOCUMENTS` SET `ONTOP` = 1 WHERE `ID` = '36' AND `DOCNAME` = (SELECT `DOCNAME` FROM `DOCUMENTS` WHERE `ID` = '36')
Спасибо!
UPDATE
`DOCUMENTS`
SET
`ONTOP` = 1
WHERE
`ID` = '36' OR
`DOCNAME` = (SELECT `DOCNAME` FROM `DOCUMENTS` WHERE `ID` = '36')
Вот вроде как-то так !

а вообще, лучше даже так
UPDATE
`DOCUMENTS`
SET
`ONTOP` = 1
WHERE
`DOCNAME` = (SELECT `DOCNAME` FROM `DOCUMENTS` WHERE `ID` = '36')
ведь и ID =36 тоже попадёт под это правило

Спустя 8 минут, 45 секунд (31.07.2008 - 15:07) QuadMan написал(а):
Цитата(jetistyum @ 31.7.2008, 11:59) [snapback]44916[/snapback]
а вообще, лучше даже так
UPDATE
`DOCUMENTS`
SET
`ONTOP` = 1
WHERE
`DOCNAME` = (SELECT `DOCNAME` FROM `DOCUMENTS` WHERE `ID` = '36')
ведь и ID =36 тоже попадёт под это правило
UPDATE
`DOCUMENTS`
SET
`ONTOP` = 1
WHERE
`DOCNAME` = (SELECT `DOCNAME` FROM `DOCUMENTS` WHERE `ID` = '36')
ведь и ID =36 тоже попадёт под это правило

Как я понимаю, SQL не позволяет использовать в подзапросе таблицу, которую собираешься изменять... как от этого избавится - неясно...
Спустя 42 минуты, 35 секунд (31.07.2008 - 15:50) jetistyum написал(а):
Цитата(QuadMan @ 31.7.2008, 15:07) [snapback]44919[/snapback]
Цитата(jetistyum @ 31.7.2008, 11:59) [snapback]44916[/snapback]
а вообще, лучше даже так
UPDATE
`DOCUMENTS`
SET
`ONTOP` = 1
WHERE
`DOCNAME` = (SELECT `DOCNAME` FROM `DOCUMENTS` WHERE `ID` = '36')
ведь и ID =36 тоже попадёт под это правило
UPDATE
`DOCUMENTS`
SET
`ONTOP` = 1
WHERE
`DOCNAME` = (SELECT `DOCNAME` FROM `DOCUMENTS` WHERE `ID` = '36')
ведь и ID =36 тоже попадёт под это правило

Как я понимаю, SQL не позволяет использовать в подзапросе таблицу, которую собираешься изменять... как от этого избавится - неясно...
ХМ.. точно..
тогда два запроса..
1. SELECT `DOCNAME` FROM `DOCUMENTS` WHERE `ID` = '36'
2. UPDATE....
Спустя 5 минут, 21 секунда (31.07.2008 - 15:55) sergeiss написал(а):
Мне так сдается, что надо написать условие немного по-другому:
WHERE
`DOCNAME` IN (SELECT `DOCNAME` FROM `DOCUMENTS` WHERE `ID` = '36')
WHERE
`DOCNAME` IN (SELECT `DOCNAME` FROM `DOCUMENTS` WHERE `ID` = '36')
Спустя 1 час, 5 минут, 56 секунд (31.07.2008 - 17:01) QuadMan написал(а):
Цитата(sergeiss @ 31.7.2008, 12:55) [snapback]44923[/snapback]
Мне так сдается, что надо написать условие немного по-другому:
WHERE
`DOCNAME` IN (SELECT `DOCNAME` FROM `DOCUMENTS` WHERE `ID` = '36')
WHERE
`DOCNAME` IN (SELECT `DOCNAME` FROM `DOCUMENTS` WHERE `ID` = '36')
Ничего не помогает.. не хочет MySQL в подзапросе использовать таблицу, которая обновляется...

Спустя 1 час, 40 минут, 43 секунды (31.07.2008 - 18:42) sergeiss написал(а):
Посидел я тут, помедитировал, глядя на запрос... И переписал свой ответ.
Тут получается интересный момент
Почему бы не написать
Зачем приплетать сюда еще одно поле??? Про указанном подзапросе предполагается, что надо изменить нечто в таблице, в которой имя документа такое, что ему соответствует идентификатор номер 36... А это как раз и есть, что просто идентификатор равен 36. DOCNAME тут лишний.
Тут получается интересный момент

Код
UPDATE
`DOCUMENTS`
SET
`ONTOP` = 1
WHERE `ID`=36
`DOCUMENTS`
SET
`ONTOP` = 1
WHERE `ID`=36
Зачем приплетать сюда еще одно поле??? Про указанном подзапросе предполагается, что надо изменить нечто в таблице, в которой имя документа такое, что ему соответствует идентификатор номер 36... А это как раз и есть, что просто идентификатор равен 36. DOCNAME тут лишний.
Спустя 44 минуты, 4 секунды (31.07.2008 - 19:26) QuadMan написал(а):
Цитата(sergeiss @ 31.7.2008, 15:42) [snapback]44932[/snapback]
Посидел я тут, помедитировал, глядя на запрос... И переписал свой ответ.
Тут получается интересный момент
Почему бы не написать
Зачем приплетать сюда еще одно поле??? Про указанном подзапросе предполагается, что надо изменить нечто в таблице, в которой имя документа такое, что ему соответствует идентификатор номер 36... А это как раз и есть, что просто идентификатор равен 36. DOCNAME тут лишний.
Тут получается интересный момент

Код
UPDATE
`DOCUMENTS`
SET
`ONTOP` = 1
WHERE `ID`=36
`DOCUMENTS`
SET
`ONTOP` = 1
WHERE `ID`=36
Зачем приплетать сюда еще одно поле??? Про указанном подзапросе предполагается, что надо изменить нечто в таблице, в которой имя документа такое, что ему соответствует идентификатор номер 36... А это как раз и есть, что просто идентификатор равен 36. DOCNAME тут лишний.
Нет, не лишний.


Спустя 12 секунд (31.07.2008 - 19:26) Professor написал(а):
Цитата
Тут получается интересный момент Почему бы не написать
Ты не совсем понял.
Человеку надо что бы ONTOP изменился у всех,у кого DOCNAME такой же как и у 36 го номера.
я тоже помедитировал,но по ходу только2мя запросами.
Спустя 13 часов, 32 минуты, 55 секунд (1.08.2008 - 08:59) sergeiss написал(а):
Тогда ХЗ...
На самом деле, я использую PostgreSQL. А MySQL удалил после недели упорной борьбы с его "особенностями".
В PostgreSQL я проверил, всё работает "как часы".
Возможно, какие-то специфические настройки есть в MySQL?
Либо, попробовать использовать нечто типа INSERT INTO .... SELECT .... ON DUPLICATE KEY UPDATE .....?
На самом деле, я использую PostgreSQL. А MySQL удалил после недели упорной борьбы с его "особенностями".
В PostgreSQL я проверил, всё работает "как часы".
Код
---
Создал базу с такой струкутурой:
CREATE TABLE docs
(
id serial NOT NULL,
docname text,
id_sub integer
)
поле id - целое с автоувеличением
---
Накидал в таблицу произвольные данные:
select * from docs order by id:
id;docname;id_sub
1;"Doc 1";1
2;"Doc 1";4
3;"Doc 7";4
4;"Doc 7";3
5;"Doc 3";3
6;"Doc 1";33
7;"Doc 5";3
8;"Doc 6";2
9;"Doc 1";2
---
Проверил подвыборку:
select *
from docs
where docname in (select docname from docs where id=4)
3;"Doc 7";4
4;"Doc 7";3
---
Запустил основной запрос на изменение
update docs
set id_sub=120
where docname in (select docname from docs where id=4)
---
Проверил, что получилось в итоге
select * from docs order by id:
1;"Doc 1";1
2;"Doc 1";4
3;"Doc 7";120
4;"Doc 7";120
5;"Doc 3";3
6;"Doc 1";33
7;"Doc 5";3
8;"Doc 6";2
9;"Doc 1";2
Создал базу с такой струкутурой:
CREATE TABLE docs
(
id serial NOT NULL,
docname text,
id_sub integer
)
поле id - целое с автоувеличением
---
Накидал в таблицу произвольные данные:
select * from docs order by id:
id;docname;id_sub
1;"Doc 1";1
2;"Doc 1";4
3;"Doc 7";4
4;"Doc 7";3
5;"Doc 3";3
6;"Doc 1";33
7;"Doc 5";3
8;"Doc 6";2
9;"Doc 1";2
---
Проверил подвыборку:
select *
from docs
where docname in (select docname from docs where id=4)
3;"Doc 7";4
4;"Doc 7";3
---
Запустил основной запрос на изменение
update docs
set id_sub=120
where docname in (select docname from docs where id=4)
---
Проверил, что получилось в итоге
select * from docs order by id:
1;"Doc 1";1
2;"Doc 1";4
3;"Doc 7";120
4;"Doc 7";120
5;"Doc 3";3
6;"Doc 1";33
7;"Doc 5";3
8;"Doc 6";2
9;"Doc 1";2
Возможно, какие-то специфические настройки есть в MySQL?
Либо, попробовать использовать нечто типа INSERT INTO .... SELECT .... ON DUPLICATE KEY UPDATE .....?
Спустя 1 час, 15 минут (1.08.2008 - 10:14) QuadMan написал(а):
Цитата(sergeiss @ 1.8.2008, 5:59) [snapback]44975[/snapback]
Тогда ХЗ...
На самом деле, я использую PostgreSQL. А MySQL удалил после недели упорной борьбы с его "особенностями".
В PostgreSQL я проверил, всё работает "как часы".
Возможно, какие-то специфические настройки есть в MySQL?
Либо, попробовать использовать нечто типа INSERT INTO .... SELECT .... ON DUPLICATE KEY UPDATE .....?
На самом деле, я использую PostgreSQL. А MySQL удалил после недели упорной борьбы с его "особенностями".
В PostgreSQL я проверил, всё работает "как часы".
Код
---
Создал базу с такой струкутурой:
CREATE TABLE docs
(
id serial NOT NULL,
docname text,
id_sub integer
)
поле id - целое с автоувеличением
---
Накидал в таблицу произвольные данные:
select * from docs order by id:
id;docname;id_sub
1;"Doc 1";1
2;"Doc 1";4
3;"Doc 7";4
4;"Doc 7";3
5;"Doc 3";3
6;"Doc 1";33
7;"Doc 5";3
8;"Doc 6";2
9;"Doc 1";2
---
Проверил подвыборку:
select *
from docs
where docname in (select docname from docs where id=4)
3;"Doc 7";4
4;"Doc 7";3
---
Запустил основной запрос на изменение
update docs
set id_sub=120
where docname in (select docname from docs where id=4)
---
Проверил, что получилось в итоге
select * from docs order by id:
1;"Doc 1";1
2;"Doc 1";4
3;"Doc 7";120
4;"Doc 7";120
5;"Doc 3";3
6;"Doc 1";33
7;"Doc 5";3
8;"Doc 6";2
9;"Doc 1";2
Создал базу с такой струкутурой:
CREATE TABLE docs
(
id serial NOT NULL,
docname text,
id_sub integer
)
поле id - целое с автоувеличением
---
Накидал в таблицу произвольные данные:
select * from docs order by id:
id;docname;id_sub
1;"Doc 1";1
2;"Doc 1";4
3;"Doc 7";4
4;"Doc 7";3
5;"Doc 3";3
6;"Doc 1";33
7;"Doc 5";3
8;"Doc 6";2
9;"Doc 1";2
---
Проверил подвыборку:
select *
from docs
where docname in (select docname from docs where id=4)
3;"Doc 7";4
4;"Doc 7";3
---
Запустил основной запрос на изменение
update docs
set id_sub=120
where docname in (select docname from docs where id=4)
---
Проверил, что получилось в итоге
select * from docs order by id:
1;"Doc 1";1
2;"Doc 1";4
3;"Doc 7";120
4;"Doc 7";120
5;"Doc 3";3
6;"Doc 1";33
7;"Doc 5";3
8;"Doc 6";2
9;"Doc 1";2
Возможно, какие-то специфические настройки есть в MySQL?
Либо, попробовать использовать нечто типа INSERT INTO .... SELECT .... ON DUPLICATE KEY UPDATE .....?
Спасибо! Значит, скорее всего, это действительно, особенность MySQL

Спустя 3 часа, 9 минут, 3 секунды (1.08.2008 - 13:23) Alchemist написал(а):
Долго медитировал глядя на этот топик...
Дети мои, запомните ! Для успешной медитации необходимо курить мануалы !
Это происходит потому, что подзапросы расположеные в WHERE при определенных условиях могут выполняться для каждой строки внешнего запроса. А поскольку вы в процессе меняете таблицу из которой берете данные, то результат такого изменения становится непредсказуем.
Там же в мануале вам предлагается решение:
Основная мысль - подзапросы расположеные в FROM всегда выполняются только один раз и сохраняются во временной таблице. Тогда ничего не мешает обращаться к ней опять и опять, её-то мы не изменяем...
Ладно, покурили и будя... Назад к нашим... гм... проблемам.
Можно, конечно, переписать запрос добавив внутри подзапроса еще один подзапрос, как это описано в мануале. Но мне кажется более простым будет вариант:
Всех благ !
PS: http://dev.mysql.com/doc/refman/5.0/en/sub...strictions.html
Дети мои, запомните ! Для успешной медитации необходимо курить мануалы !
Цитата(MySQL Manual)
In general, you cannot modify a table and select from the same table in a subquery. For example, this limitation applies to statements of the following forms:
Код
DELETE FROM t WHERE ... (SELECT ... FROM t ...);
UPDATE t ... WHERE col = (SELECT ... FROM t ...);
{INSERT|REPLACE} INTO t (SELECT ... FROM t ...);
UPDATE t ... WHERE col = (SELECT ... FROM t ...);
{INSERT|REPLACE} INTO t (SELECT ... FROM t ...);
Это происходит потому, что подзапросы расположеные в WHERE при определенных условиях могут выполняться для каждой строки внешнего запроса. А поскольку вы в процессе меняете таблицу из которой берете данные, то результат такого изменения становится непредсказуем.
Там же в мануале вам предлагается решение:
Цитата(MySQL Manual)
Exception: The preceding prohibition does not apply if you are using a subquery for the modified table in the FROM clause. Example:
Here the prohibition does not apply because the result from a subquery in the FROM clause is stored as a temporary table, so the relevant rows in t have already been selected by the time the update to t takes place.
Код
UPDATE t ... WHERE col = (SELECT * FROM (SELECT ... FROM t...) AS _t ...);
Here the prohibition does not apply because the result from a subquery in the FROM clause is stored as a temporary table, so the relevant rows in t have already been selected by the time the update to t takes place.
Основная мысль - подзапросы расположеные в FROM всегда выполняются только один раз и сохраняются во временной таблице. Тогда ничего не мешает обращаться к ней опять и опять, её-то мы не изменяем...
Ладно, покурили и будя... Назад к нашим... гм... проблемам.
Можно, конечно, переписать запрос добавив внутри подзапроса еще один подзапрос, как это описано в мануале. Но мне кажется более простым будет вариант:
Код
UPDATE `DOCUMENTS` AS `changing`
INNER JOIN `DOCUMENTS` AS `selector` USING(`DOCNAME`)
SET `changing`.`ONTOP` = 1
WHERE `selector`.`ID` = '36'
INNER JOIN `DOCUMENTS` AS `selector` USING(`DOCNAME`)
SET `changing`.`ONTOP` = 1
WHERE `selector`.`ID` = '36'
Всех благ !
PS: http://dev.mysql.com/doc/refman/5.0/en/sub...strictions.html
Спустя 1 час, 40 минут, 35 секунд (1.08.2008 - 15:04) QuadMan написал(а):
Alchemist
Огромное спасибо за разъяснения!!!!
Теперь буду еще лучше курить мануалы
)
А вот все-таки одну вещь я не понял...
но ведь в моем подзапросе не изменялись колонки, которые обновлялись в UPDATE... UPDATE затрагивает только ONTOP, а подселект выбирает DOCNAME по ID.
Вроде бы ничего непредсказуемого не происходит в таком случае...
Огромное спасибо за разъяснения!!!!


А вот все-таки одну вещь я не понял...

Цитата
Это происходит потому, что подзапросы расположеные в WHERE при определенных условиях могут выполняться для каждой строки внешнего запроса. А поскольку вы в процессе меняете таблицу из которой берете данные, то результат такого изменения становится непредсказуем.
но ведь в моем подзапросе не изменялись колонки, которые обновлялись в UPDATE... UPDATE затрагивает только ONTOP, а подселект выбирает DOCNAME по ID.

Спустя 1 час, 17 минут, 12 секунд (1.08.2008 - 16:21) Alchemist написал(а):
Цитата(QuadMan @ 1.8.2008, 15:04) [snapback]45016[/snapback]
но ведь в моем подзапросе не изменялись колонки, которые обновлялись в UPDATE... UPDATE затрагивает только ONTOP, а подселект выбирает DOCNAME по ID.
Вроде бы ничего непредсказуемого не происходит в таком случае...

Ты прав, в твоем случае не происходит. Но это всего лишь частный (и весьма простой) случай общего правила. Ведь подзапрос в свою очередь может быть довольно сложным запросом со своими позапросами и разветвлениями. А если мы еще учтем, что подзапросы могут обращаться и использовать поля таблиц из внешних запросов... Вобщем без поллитры не всегда разберешься.
На самом деле, теоретически, всё это можно проверить и разделить на случаи "можно" и "нельзя". Но это теоретически, а практически создатели MySQL, по-видимому, еще не нашли эффективного механизма для этого. Но они продолжают искать

Цитата(MySQL Manual)
...Another restriction is that currently you cannot modify a table and select from the same table in a subquery.
Спустя 2 часа, 58 минут, 22 секунды (1.08.2008 - 19:19) sergeiss написал(а):
Но тогда получается, что создатели PostgreSQL нашли этот механизм?
Спустя 9 часов, 32 минуты, 23 секунды (2.08.2008 - 04:52) Alchemist написал(а):
Цитата(sergeiss @ 1.8.2008, 19:19) [snapback]45046[/snapback]
Но тогда получается, что создатели PostgreSQL нашли этот механизм?
Возможно...
Или они не разрешают делать что-то другое в запросах, что MySQL позволяет (например нельзя делать зависимые подзапросы)...
Или у них другой алгоритм обработки запроса/подзапроса...
Или другой алгоритм изменения данных (например внутренние транзакции)...
Или они просто предполагают, что юзер сам должен думать что он делает...
Вобщем тут много причин может быть. Я, увы, не копенгаген в постгре, чтобы конкретно указать на нее...
_____________