我试图通过select查询的结果更新表中的值。问题是我不允许在最里面的表的Order By子句中引用最外面的表(正在更新的表)(用于选择新值的表)。
假设我有下表:
MustMatch PreferredMatch Old New
---------- -------------- ---------- ----------
0 Blue Old blue
1 Blue Wrong matc
0 Red Unpreferre
0 Blue Preferred
我想填写“Old blue”的“New”栏目。新值必须与旧值不同,但在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
的引用。当我执行
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
为什么我不允许在Order By子句中使用表t
,即使我可以在Where子句中使用它?还有另一种方法可以达到这个目的吗?
答案 0 :(得分:0)
我很惊讶您的版本不起作用。这是一个强力解决方案:
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
);
答案 1 :(得分:0)
如果不是
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中你可以使用外部表中正在更新的字段)。
恕我直言,这是sqlite中的一个错误 - 没有理由为什么来自外部表的字段可以用在where和select子句中但不能用于order-by。
答案 2 :(得分:0)
请注意,postgresql中的完全相同的运行只是起作用:
var express = require('express');
var app = express();
var firebase = require('firebase');
app.get('/', function (req, res) {
res.sendFile(__dirname + '/html/index.html');
});
app.get('/welcome', function (req, res) {
res.sendFile(__dirname + '/html/welcome.html');
});
这真的感觉像sqlite错误 - 在子选择中使用外部字段应该没有区别。