使用rowid在sqlite中的公用表表达式

问题描述 投票:2回答:1

我发现了一篇关于在http://dataeducation.com/the-hidden-costs-of-insert-exec/将邻接转换为嵌套集的好文章

使用的SQL语言是Microsoft SQL Server(我认为),我试图将文章中给出的示例转换为sqlite(因为这是我在Macbook上轻松访问的内容)。

我似乎遇到的问题是将整个CTE查询的一部分转换为Employee Rows

EmployeeRows AS
(
    SELECT
         EmployeeLevels.*,
         ROW_NUMBER() OVER (ORDER BY thePath) AS Row
    FROM EmployeeLevels
)

我把它改成了

EmployeeRows AS
(
    SELECT
         EmployeeLevels.*,
         rowid AS Row
    FROM EmployeeLevels
    ORDER BY thePath
)

并运行CTE查询(没有语法错误),但我得到的输出是没有填充Row和Lft和Rgt列的表

ProductName  ProductID   ParentProductID  TreePath    HLevel      Row         Lft         Rgt       
-----------  ----------  ---------------  ----------  ----------  ----------  ----------  ----------
Baby Goods   0                            0           1                                             
Baby Food    10          0                0.10        2                                             
All Ages Ba  100         10               0.10.100    3                                             
Strawberry   200         100              0.10.100.2  4                                             
Baby Cereal  250         100              0.10.100.2  4                                             
Beginners    150         10               0.10.150    3                                             
Formula Mil  300         150              0.10.150.3  4                                             
Heinz Formu  310         300              0.10.150.3  5                                             
Nappies      20          0                0.20        2                                             
Small Pack   400         20               0.20.400    3                                             
Bulk Pack N  450         20               0.20.450    3                                             

我认为问题的开始是Row没有填充,因此Lft和Rgt列不会被查询的以下部分填充。

有没有sqlite专家告诉我:

  • 我正确地翻译了查询的rowid部分
  • sqlite是否支持CTE查询的一部分中的rowid
  • 有没有更好的办法? :)

任何帮助赞赏:)

sqlite common-table-expression nested-sets adjacency-list
1个回答
0
投票

我正确地翻译了查询的rowid部分

没有。

SQL:

SELECT
     EmployeeLevels.*,
     rowid AS Row
FROM EmployeeLevels
ORDER BY thePath

Row定义为SQLite中表EmployeeLevels的rowid,忽略order子句。这与ROW_NUMBER() OVER (ORDER BY thePath) AS Row的意图不同

sqlite是否支持CTE查询的一部分中的rowid

很不幸的是,不行。我猜你的意思是:

WITH foo AS (
   SELECT * FROM bar ORDER BY col_a
)
SELECT rowid, *
FROM foo

但SQLite将在rowid中报告没有这样的foo列。

有没有更好的办法?

不确定它是否更好,但至少它是有效的。在SQLite中,只要您的连接打开并且您没有故意删除它,就会存在临时表机制。在我的示例中重写上面的SQL:

CREATE TEMP TABLE foo AS 
SELECT * FROM bar ORDER BY col_a
;
SELECT rowid, *
FROM foo
;
DROP TABLE foo
;

这个将在没有SQLite抱怨的情况下运行。

更新:

从SQLite版本3.25.0开始,支持窗口功能。因此,如果您碰巧使用较新的SQLite,则可以在CTE中使用row_number() over (order by x)表达式

© www.soinside.com 2019 - 2024. All rights reserved.