【问题标题】:How to write the sql in SQLite with this?如何用这个在 SQLite 中编写 sql?
【发布时间】:2021-04-18 22:08:35
【问题描述】:
    WITH cteCountDownlines AS
( --=== Count each occurrence of EmployeeID in the sort path
 SELECT EmployeeID = CAST(SUBSTRING(h.SortPath,t.N,4) AS INT), 
        NodeCount  = COUNT(*) --Includes current node
   FROM dbo.Hierarchy h, 
        dbo.HTally t
  WHERE t.N BETWEEN 1 AND DATALENGTH(SortPath)
  GROUP BY SUBSTRING(h.SortPath,t.N,4)
) --=== Update the NodeCount and calculate the RightBower
 UPDATE h
    SET h.NodeCount  = downline.NodeCount,
        h.RightBower = (downline.NodeCount - 1) * 2 + LeftBower + 1
   FROM dbo.Hierarchy h
   JOIN cteCountDownlines downline
     ON h.EmployeeID = downline.EmployeeID
;

来自https://www.sqlservercentral.com/articles/hierarchies-on-steroids-1-convert-an-adjacency-list-to-nested-sets。 我尝试了很多方法,但没有奏效。 分开的 cteCountDownlines 和 join 工作得很好,但不知道如何结合它们

【问题讨论】:

  • 你的 SQLite 版本是多少?
  • 这到底是怎么回事——看起来不错。
  • @forpas 我尝试在 SQLite 中使用 join,但它们都不起作用..而且我完全没有 JOIN 的版本。

标签: sql sqlite sql-update common-table-expression


【解决方案1】:

如果您使用的是 SQLite 3.33.0+,则可以使用 UPDATE...FROM 语法:

WITH cteCountDownlines AS (
 SELECT CAST(SUBSTR(h.SortPath,t.N,4) AS INT) EmployeeID, 
        COUNT(*) NodeCount
  FROM Hierarchy h INNER JOIN HTally t
  ON t.N BETWEEN 1 AND LENGTH(h.SortPath)
  GROUP BY SUBSTR(h.SortPath,t.N,4)
)
UPDATE Hierarchy AS h
SET NodeCount  = downline.NodeCount,
    RightBower = (downline.NodeCount - 1) * 2 + h.LeftBower + 1
FROM cteCountDownlines downline
WHERE h.EmployeeID = downline.EmployeeID;

对于 SQLite 3.15.0+,您可以使用以下语法:

WITH cteCountDownlines AS (
 SELECT CAST(SUBSTR(h.SortPath,t.N,4) AS INT) EmployeeID, 
        COUNT(*) NodeCount
  FROM Hierarchy h INNER JOIN HTally t
  ON t.N BETWEEN 1 AND LENGTH(h.SortPath)
  GROUP BY SUBSTR(h.SortPath,t.N,4)
)
UPDATE Hierarchy AS h
SET (NodeCount, RightBower) = (
  SELECT downline.NodeCount,
         (downline.NodeCount - 1) * 2 + h.LeftBower + 1
  FROM cteCountDownlines downline
  WHERE h.EmployeeID = downline.EmployeeID
);

请注意,没有等效于 SQL Server 的 DATALENGTH() 函数。
我使用的函数LENGTH()返回字符串中的字符数。

【讨论】:

  • 非常感谢!同时,我试图完成我的版本,它看起来很有效,而且和你的完全一样...codepad.org/OXTMDKg7(我的表名不同)我很困惑为什么他的版本使用了 JOIN?似乎根本没有加入操作。
  • @T.Worm 您问题中的链接页面使用 SQL Server 语法,SQLite 不支持该语法。 SQLite 的 UPDATE FROM 语法类似于 Postgres。
  • 对不起,这可能超出了主题。我使用了这个 codepad.org/P5E6jLcT 而不是 CAST(anchor.EmployeeID AS BINARY(4)) 之类的东西。我想知道这是否会导致性能?
  • SQLite 中没有 BINARY 数据类型。阅读本文:sqlite.org/datatype3.html 至于其余代码,乍一看我唯一能说的是递归查询(取决于递归的深度)可能对性能不利。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-24
  • 1970-01-01
  • 1970-01-01
  • 2015-10-27
  • 1970-01-01
  • 2012-11-01
  • 2017-11-18
相关资源
最近更新 更多