无法更新位置,订购依据和限额

时间:2018-09-26 07:58:26

标签: sql sqlite sql-update

我正在使用SQLite 3。

当我输入以下查询

UPDATE MyTable Set Flag = 1 WHERE ID = 5 Order By OrderID DESC LIMIT 1;

我总是会报错:

  

订购者附近,语法错误

我无法弄清楚我的查询出了什么问题

6 个答案:

答案 0 :(得分:3)

要在UPDATE或DELETE语句中使用LIMIT和ORDER BY,您必须做两件事:

  • 从源代码构建sqlite3.c合并的自定义版本,并使用--enable-update-limit选项对其进行配置。
  • SQLITE_ENABLE_UPDATE_DELETE_LIMIT定义为1的自定义sqlite3.c编译到您的项目中。

答案 1 :(得分:2)

“ Order By OrderID DESC LIMIT 1”用于选择排名前1的结果 因此您应该在选择查询中使用它。 您应该在子查询中首先获取ID,然后对其进行更新:

UPDATE  MyTable 
SET Flag = 1 
WHERE (ID,OrderID) IN (SELECT ID,OrderID
FROM MyTable 
WHERE ID = 5 
ORDER BY OrderID DESC LIMIT 1);

Demo

答案 2 :(得分:1)

您可以使用ROWID

UPDATE MyTable 
SET Flag = 1 
WHERE ROWID IN (SELECT ROWID FROM MyTable WHERE ID = 5 
                ORDER BY OrderID DESC LIMIT 1);

db<>fiddle demo

(ID,OrderID)元组:

UPDATE  MyTable 
SET Flag = 1 
WHERE (ID, ORDERID) IN (SELECT  ID, ORDERID FROM MyTable WHERE ID = 5 
                        ORDER BY OrderID DESC LIMIT 1);

db<>fiddle demo2


如果需要为每个ID(SQLite 3.25.0)批量执行此操作:

WITH cte AS (
  SELECT *,ROW_NUMBER() OVER(PARTITION BY ID ORDER BY OrderID DESC) AS rn FROM tab
)
UPDATE tab
SET Flag = 1
WHERE (ID, OrderID) IN (
       SELECT ID, OrderID
       FROM cte
       WHERE rn = 1
      );

答案 3 :(得分:1)

Order By语句在更新查询中不起作用。 您必须使用其他方式

    var results = primes.Where(p => p > 3);

如果您已使用上述查询,那么它将起作用。

答案 4 :(得分:0)

简介

下面,我提出两种解决方案来解决该问题并执行适当的UPDATE。每个解决方案的最后都有一个包含示例数据的实时示例。

  • 第一不需要您输入任何id,而是通过为每个orderid选择最新的id并更改来为整个表格工作从flag1

  • 第二要求您输入一个id,并且只能在运行时更新一个id

我个人会选择 first 解决方案,但是我不确定您的要求,因此发布了两种可能性。

第一个解决方案-更新整个表格

说明在此处,用于代码向下滚动。

为此,我们将使用Row Value构造(id, orderid),就像第二个解决方案一样。 它将基于orderid查找最新行,并仅针对给定的(id, orderid)对更新该行。有关更多信息,请参见第二种解决方案的说明。

我们还需要模拟row_number函数来为每一行分配排名数字,以找出哪一行在每个orderid中拥有最新的id并将其标记为{{1} },以便仅提取其中的内容进行更新。这将使我们能够在一条语句中针对不同的ID更新多行。 SQLite将具有此功能built in version 3.2.5,但现在,我们将使用子查询。

要生成行号,我们将使用以下代码:

1

然后,我们只需要过滤select *, (select count(*) from mytable m1 where m1.id = m2.id and m1.orderid >= m2.orderid) as rn from mytable m2 上的输出,我们便有了所需的东西。

也就是说,整个rn = 1语句如下所示:

代码

UPDATE

实时演示

在这里 db fiddle 可以在示例数据上实时查看此解决方案。


第二种解决方案-仅更新一个ID

如果您知道自己的update mytable set flag = 1 where (id,orderid) in ( select id, orderid from ( select *, (select count(*) from mytable m1 where m1.id = m2.id and m1.orderid >= m2.orderid) as rn from mytable m2 ) m where m.rn = 1 and m.id = mytable.id ); 要更新,并且只想为一个ID运行ID语句,那么它将起作用:

代码

UPDATE

说明

update mytable set flag = 1 where (id,orderid) in ( select id, orderid from mytable where id = 5 order by orderid desc limit 1 ); 是一个名为Row Value的构造,SQLite为此对其从左到右比较标量值。

示例摘自文档:

(id, orderid)

实时演示

在这里 db fiddle 可以在示例数据上实时查看此解决方案。

答案 5 :(得分:0)

SQL

UPDATE MyTable
SET Flag = 1
WHERE ID = 5
AND OrderID IN (SELECT OrderID
                FROM MyTable
                WHERE ID = 5
                ORDER BY OrderID DESC
                LIMIT 1);

演示

SQLFiddle演示:http://sqlfiddle.com/#!5/6d596/2