我发现了一篇关于在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部分
没有。
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)
表达式