【问题标题】:Create recursive query SQLite3 Get parent from child创建递归查询SQLite3从孩子获取父母
【发布时间】:2021-06-29 05:37:45
【问题描述】:

在创建递归查询方面需要帮助

现有数据:

我们有办公室(Type-1)、部门(Type-2)和员工(Type-3)

需要获取所选员工的办公室名称和该办公室的所有员工姓名

例如:输入 13 (它是员工 ID) 我们得到输出:“Офис в Москве: Винтиков, Шпунтиков, Белова, Крылова, Петрова, Иванова。”

【问题讨论】:

    标签: sql sqlite recursion


    【解决方案1】:

    您可以为此目的使用joins。要获取办公室的员工人数,您可以使用:

    select td.parentid,
           sum(case when te.type = 3 then 1 else 0 end) as num_employees
    from t td join
         t te
         on te.parentid = td.id
    where t3.type = 3
    group by td.parentid;
    

    然后,您还需要一个join 来获取姓名和一个having 子句来查看办公室是否有特定员工:

    select to.id, to.name,
           sum(case when te.type = 3 then 1 else 0 end) as num_employees
    from to join
         t td
         on td.parentid = to.id join
         t te
         on te.parentid = td.id
    where t3.type = 3
    group by to.id, to.name
    having sum(case when t3.name = ? then 1 else 0 end) > 0;
    

    【讨论】:

      【解决方案2】:

      我在 Python 上解决了这个问题:

      SQLite 表:

      CREATE TABLE IF NOT EXISTS "row" (
        "Id"  INTEGER NOT NULL UNIQUE,
        "ParentId"    REFERENCES row,
        "Name"    TEXT NOT NULL,
        "Type"    INTEGER NOT NULL CHECK(Type > 0 AND Type <= 3),
      PRIMARY KEY("Id"))
      

      通过员工 ID 递归查找办公室:

      index = 13
      cursor.execute(
        f"""
          SELECT * FROM row WHERE Id={index}
        """
      )
      
      selected_employee = cursor.fetchone()
      
      cursor.execute(
        f"""
          WITH RECURSIVE
            over_employee(Id, ParentId, Name, Type, level)
            AS (
              VALUES({index}, {selected_employee[1]}, "{selected_employee[2]}", {selected_employee[3]}, 0)
              UNION ALL
              SELECT row.Id, row.ParentId, row.Name, row.Type, over_employee.level+1
              FROM row JOIN over_employee ON row.Id=over_employee.ParentId
              )
            SELECT Id, Name, Type, level FROM over_employee;
        """
      )
      
      employee_office = cursor.fetchall()[-1]
      

      递归地找出结果办公室的所有员工:

      cursor.execute(
        f"""
          WITH RECURSIVE
          under_office(Id, Name, Type, level) AS (
            VALUES({employee_office[0]}, "{employee_office[1]}", {employee_office[2]}, 0)
            UNION ALL
            SELECT row.Id, row.Name, row.Type, under_office.level+1
              FROM row JOIN under_office ON row.ParentId=under_office.Id
          )
          SELECT Name FROM under_office WHERE Type=3;
        """
      )
      
      print("Output:")
      print("{}:".format(employee_office[1]), end=' ')
      for res in cursor:
        print(res[0], end=', ')
      

      输出:

      Офис в Москве: Винтиков, Шпунтиков, Морозов, Белова, Крылова, Иванова, Петрова,

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-23
        相关资源
        最近更新 更多