Я пытаюсь обновить значения в таблице по результатам запроса на выборку. Проблема в том, что мне не разрешено ссылаться на самую внешнюю таблицу (обновляемую) в предложении Order By самой внутренней таблицы (таблица для выбора нового значения).
Предположим, у меня есть следующая таблица:
MustMatch PreferredMatch Old New
---------- -------------- ---------- ----------
0 Blue Old blue
1 Blue Wrong matc
0 Red Unpreferre
0 Blue Preferred
Я хочу заполнить столбец «Новый» на «Старый синий». Новое значение должно отличаться от старого, но соответствовать столбцу MustMatch. Следующий запрос сделает это:
UPDATE t
SET New = (
SELECT innerTable.Old
FROM t innerTable
WHERE innerTable.Old != t.Old
AND innerTable.MustMatch = t.MustMatch
LIMIT 1
) WHERE Old = "Old blue";
MustMatch PreferredMatch Old New
---------- -------------- ---------- -----------------
0 Blue Old blue Unpreferred match
1 Blue Wrong matc
0 Red Unpreferre
0 Blue Preferred
Теперь я хочу добавить предпочтение: я хочу добавить ORDER BY innerTable.PreferredMatch = t.PreferredMatch
во внутренний запрос:
UPDATE t
SET New = (
SELECT innerTable.Old
FROM t innerTable
WHERE innerTable.Old != t.Old
AND innerTable.MustMatch = t.MustMatch
ORDER BY innerTable.PreferredMatch = t.PreferredMatch DESC
LIMIT 1
) WHERE Old = "Old blue";
Это вызывает ошибку Error: no such column: t.PreferredMatch
.
Проблема заключается в ссылке на t
. Предложение Order By работает так, как задумано, когда я
UPDATE t
SET New = (
SELECT innerTable.Old
FROM t innerTable
WHERE innerTable.Old != t.Old
AND innerTable.MustMatch = t.MustMatch
ORDER BY innerTable.PreferredMatch = 'Blue' DESC
LIMIT 1
) WHERE Old = "Old blue";
MustMatch PreferredMatch Old New
---------- -------------- ---------- ---------------
0 Blue Old blue Preferred match
1 Blue Wrong matc
0 Red Unpreferre
0 Blue Preferred
Почему мне не разрешено использовать таблицу t
в предложении Order By, хотя я могу использовать его в предложении Where? Есть ли другой способ добиться этого?
3 ответа
Если вместо
UPDATE test
SET New = (
SELECT innerTable.Old
FROM test innerTable
WHERE innerTable.Old != test.Old
AND innerTable.MustMatch = test.MustMatch
ORDER BY innerTable.PreferredMatch = test.PreferredMatch DESC
LIMIT 1
) WHERE Old = "Old blue";
Вы используете еще один уровень
UPDATE test
SET New = (SELECT newValue FROM
(SELECT innerTable.Old as newValue,
innerTable.PreferredMatch = test.PreferredMatch as pick
FROM test innerTable
WHERE innerTable.Old != test.Old
AND innerTable.MustMatch = test.MustMatch
ORDER BY pick DESC
LIMIT 1) foo
) WHERE Old = "Old blue";
Затем он работает (вы используете по порядку имя поля в select, а в select вы можете использовать поле из внешней таблицы, которая обновляется).
IMHO, это ошибка в sqlite - нет причин, по которым поле из внешней таблицы может использоваться в предложениях where и select, но не по порядку.
Я удивлен, что ваша версия не работает. Вот решение грубой силы:
UPDATE t
SET New = COALESCE((SELECT it.Old
FROM t it
WHERE it.Old <> t.Old AND
it.MustMatch = t.MustMatch AND
it.PreferredMatch = t.PreferredMatch
LIMIT 1
),
(SELECT it.Old
FROM t it
WHERE it.Old <> t.Old AND
it.MustMatch = t.MustMatch AND
it.PreferredMatch <> t.PreferredMatch
LIMIT 1
))
WHERE Old = 'Old blue';
Или это может сработать:
UPDATE t
SET New = (SELECT COALESCE(MAX(CASE WHEN it.PreferredMatch = t.PreferredMatchit.Old
THEN t.Old
END),
MAX(t.Old))
FROM t it
WHERE it.Old <> t.Old AND
it.MustMatch = t.MustMatch AND
);
Обратите внимание, что точно такой же запуск в postgresql просто работает:
create table test (MustMatch integer,
PreferredMatch varchar,
Old varchar,
New varchar);
-- CREATE TABLE
insert into test (MustMatch, PreferredMatch, Old, New)
values
(0 ,'Blue' ,'Old blue' ,null),
(1 ,'Blue' ,'Wrong matc' ,null),
(0 ,'Red' ,'Unpreferre' ,null),
(0 ,'Blue' ,'Preferred' ,null);
-- INSERT 0 4
UPDATE test
SET New = (
SELECT innerTable.Old
FROM test innerTable
WHERE innerTable.Old != test.Old
AND innerTable.MustMatch = test.MustMatch
ORDER BY innerTable.PreferredMatch = test.PreferredMatch DESC
LIMIT 1
) WHERE Old = 'Old blue';
-- UPDATE 1
Это действительно похоже на ошибку sqlite - не должно быть разницы, где вы будете использовать внешнее поле в подзапросе.
Похожие вопросы
Новые вопросы
sql
Язык структурированных запросов (SQL) - это язык запросов к базам данных. Вопросы должны включать примеры кода, структуру таблицы, примеры данных и тег для используемой реализации СУБД (например, MySQL, PostgreSQL, Oracle, MS SQL Server, IBM DB2 и т. Д.). Если ваш вопрос относится исключительно к конкретной СУБД (использует определенные расширения / функции), используйте вместо этого тег этой СУБД. Ответы на вопросы, помеченные SQL, должны использовать стандарт ISO / IEC SQL.