递归CTE查询适用于SQLiteSpy(并非总是),并且在Python上失败

时间:2014-10-10 16:50:28

标签: python sqlite recursive-query

以下代码创建一个包含几条记录的数据库,然后执行递归查询,然后使用UNION运算符执行相同的递归查询。

如果我使用sqlite 3.8.3.1在Python 3.4.0上运行代码,则第一个递归查询会起作用,但第二个会失败。

如果我使用sqlite 3.8.4.3在SQLiteSpy内运行相同的代码,则两个查询都会成功。

如果我反转UNION操作数的顺序(简单查询UNION递归查询而不是递归查询UNION简单查询),那么它在SQLiteSpy中也会失败。

release notes of SQLite中,我没有找到任何会影响行为差异的内容。

如何让递归查询在Python中运行?

import sqlite3
db = sqlite3.connect(':memory:')
cur = db.cursor()

print('preparing stuff')
cur.executescript("""DROP TABLE IF EXISTS Parts;

CREATE TABLE Parts ( 
    Id       INTEGER PRIMARY KEY,
    Desc     TEXT,
    ParentId INTEGER
);

INSERT INTO Parts VALUES (1,  'CEO',                  NULL);
INSERT INTO Parts VALUES (2,  'VIP Sales',            1);
INSERT INTO Parts VALUES (3,  'VIP Operations',       1);
INSERT INTO Parts VALUES (4,  'Sales Manager Europe', 2);
INSERT INTO Parts VALUES (5,  'Sales Manager USA',    2);
INSERT INTO Parts VALUES (6,  'Sales Rep Europe 1',   4);
INSERT INTO Parts VALUES (7,  'Sales Rep Europe 2',   4);
INSERT INTO Parts VALUES (8,  'Sales Rep USA 1',      5);
INSERT INTO Parts VALUES (9,  'Sales Rep USA 2',      5);""")

print('executing simple query')
cur.executescript("""WITH RECURSIVE Cte (
    Level,
    Id,
    Desc,
    ParentId,
    ParentDesc
  ) AS (
    SELECT 0,
           Child.Id,
           Child.Desc,
           Parent.Id,
           Parent.Desc
      FROM Parts AS Child
           JOIN Parts AS Parent ON Child.ParentId = Parent.Id
     WHERE Child.Desc = 'Sales Rep USA 1'

     UNION ALL

    SELECT Cte.Level + 1,
           Child.Id,
           Child.Desc,
           Parent.Id,
           Parent.Desc
      FROM Parts as Child, Cte
           JOIN Parts AS Parent ON Child.ParentId = Parent.Id
     WHERE Child.Id = Cte.ParentId
)
SELECT ParentId,
       ParentDesc
  FROM Cte;""")

print('executing query with union')
cur.executescript("""WITH RECURSIVE Cte (
    Level,
    Id,
    Desc,
    ParentId,
    ParentDesc
  ) AS (
    SELECT 0,
           Child.Id,
           Child.Desc,
           Parent.Id,
           Parent.Desc
      FROM Parts AS Child
           JOIN Parts AS Parent ON Child.ParentId = Parent.Id
     WHERE Child.Desc = 'Sales Rep USA 1'

     UNION ALL

    SELECT Cte.Level + 1,
           Child.Id,
           Child.Desc,
           Parent.Id,
           Parent.Desc
      FROM Parts as Child, Cte
           JOIN Parts AS Parent ON Child.ParentId = Parent.Id
     WHERE Child.Id = Cte.ParentId
)
SELECT ParentId,
       ParentDesc
  FROM Cte

UNION ALL

SELECT Id,
       Desc
  FROM Parts
 WHERE Desc = 'Sales Rep USA 1';""")

0 个答案:

没有答案