【问题标题】:SQLite : Need reference to "current" row in a UPDATESQLite:需要在 UPDATE 中引用“当前”行
【发布时间】:2017-07-03 23:02:24
【问题描述】:

我正在使用一个表示树的 SQLite 表。其列包括idparent。当然,每个parent 值都是另一行的id

还有一个 changeCount 列,对于在批量操作中删除的每个子项,我必须将其递增 1。

比如说

  • ID 为 11、12 和 13 的行将在批量操作中被删除。
  • id=11 和 id=12 的行都有相同的 parent=5。
  • id=13 的行有 parent=8。

那么id=5的行的changeCount应该加2,id=8的行的changeCount应该加1。

似乎应该有一种方法可以在一个查询中执行此操作。也许是这样的:

UPDATE myTable
    SET changeCount = changeCount
    + (SELECT COUNT(*) FROM myTable
       WHERE id IN (11,12,13) AND parent = XXXX);

表达式 XXXX 应该是对“当前”行的引用;正在设置其 changeCount 的那个。有没有这样的表达方式?或者有没有更好的方法来解决这个问题?

【问题讨论】:

  • SQLite 是一个嵌入式数据库,旨在与“真正的”编程语言一起使用。为什么要避免多个 SQL 语句?
  • 有趣的评论,@CL!老实说,我 98% 的经验是使用“真正的”编程语言。使用 SQLite,我一直是一个简单的 SELECT 和 UPDATE 类型的人,羡慕那些似乎可以用一条花哨的 SQL 语句表达相当复杂的需求的数据库专家。当我在这里遇到这个要求时,我认为这只是中级水平,所以我会试一试花哨的 SQL。可能是我低估了这个要求的难度?

标签: sqlite subquery in-subquery


【解决方案1】:

感谢@CL 的评论,我在此将我之前工作但混乱的答案编辑成一个看起来相当不错的答案:

UPDATE myTable
  SET changeCount = changeCount
    + ifnull( 
      (SELECT theCount FROM (SELECT parent AS theParent, COUNT(*) AS theCount FROM myTable WHERE id IN (11,12,13) GROUP BY parent) WHERE theParent = id)
      , 0);

ifnull() 的原因是第 4 行末尾的 id 使该子查询成为相关子查询,该查询针对表中的每一行进行评估,并且对于没有删除任何子项的行,它计算结果为 NULL。

我想知道是否可以通过使用两个查询来提高性能,首先将子查询(第 4 行)作为独立查询运行,向程序返回一个字典,其键是删除孩子的父母的 id,值是如何它的许多孩子正在被删除。但我的问题是如何在一个查询中做到这一点:)

更新:以上方法在家也可以,但不要在工作中尝试

我应该更多地考虑@CL 的原始评论。尽管这个答案有效,但在包含数万行的真实 SQLite 数据库上的性能非常糟糕。

教训:像这个“答案”这样的花哨的 SQL 查询是有趣的脑筋急转弯,但在实践中,如果性能很重要,如果你有一个真正的编程语言可用,你应该改用简单的查询并以真正的语言进行处理。

这就是我在产生这个问题的真实案例中最终所做的。

【讨论】:

  • ifnull() 可能会有所帮助。
  • 确实如此,@CL!关于您对这个问题的评论,具有讽刺意味的是,我处理过的所有“真正的”编程语言都没有这样的功能。
猜你喜欢
  • 1970-01-01
  • 2022-01-01
  • 1970-01-01
  • 2021-01-08
  • 2018-09-12
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
相关资源
最近更新 更多