我正在使用PostgreSQL。 我有一些表格。在最后一栏中有'Y'或'N'字母。我需要命令,首先选择匹配(我的意思是最后一列为'N')并在'Y'上更改。
我的想法:
UPDATE Table SET Checked='Y'
WHERE (SELECT Checked FROM Table WHERE Checked='N' ORDER BY ID LIMIT 1) = 'N'
但它在每一行都将'N'改为'Y'。
答案 0 :(得分:24)
其他人已经回答了如何,但你真的需要理解为什么这是错误的:
UPDATE Table SET Checked='Y' WHERE (
SELECT Checked FROM Table WHERE Checked='N' ORDER BY ID LIMIT 1
) = 'N'
SQL以明确定义的顺序逐步评估。在这种情况下,子查询首先进行求值,因为它是不相关的,即它不引用外部查询中的任何变量。
子查询以id
顺序查找第一行,其中'Checked'为'N',并且SELECT列表包含字段Checked
,这意味着子查询将替换值{ {1}}。实际上它什么都不做(除非它没有匹配,否则它可能是N
而不是NULL
。)
所以现在你有:
N
开始看看出了什么问题?
UPDATE Table SET Checked='Y' WHERE 'N' = 'N';
总是如此。所以'N' = 'N'
子句总是正确的,你也可以编写一个无约束的更新。
WHERE
您正在尝试找到UPDATE Table SET Checked='Y';
为checked
的第一行,并将n
设置为checked
。您需要使用主键连接这两个部分。找到您要更新的y
,然后使用它来约束更新。
其他人已经写过该查询的文字,所以我在此不再赘述。但是,希望你现在能理解这些答案。
答案 1 :(得分:16)
这是查询
UPDATE Table SET Checked='Y'
WHERE ID =(SELECT ID FROM Table WHERE Checked='N' ORDER BY ID LIMIT 1)
答案 2 :(得分:0)
请注意,如果您有并发请求,则需要处理事务,例如-
UPDATE Table SET Checked='Y' WHERE ID =(SELECT ID FROM Table WHERE Checked='N' ORDER BY ID LIMIT 1 FOR UPDATE SKIP LOCKED)
如果要跳过锁定的行
答案 3 :(得分:-2)
mssql示例:
UPDATE Table SET Checked='Y'
WHERE ID =(SELECT top 1 ID FROM Table WHERE Checked='N')
oracle示例:
UPDATE Table SET Checked='Y'
WHERE ID =(SELECT ID FROM Table WHERE Checked='N' and rownum<2)