запит батьків у дереві

Я маю таблицю бази даних Завдання, як показано нижче.

SELECT _id,name,parentId FROM Task;

_id         name                  parentId  
----------  --------------------  ----------
4           Software Development            
5           Machine Learning                
6           Programing            4         
7           Build System          4         
8           version control       4         
9           Android App Developm  4         
10          Udacity Cource        5         
11          Mathematics           5         
12          skLearn docs          5         
13          problem solving       6         
14          breakdown             13        
15          language              6         
16          c                     15        
17          C++                   15        
18          java                  15        
19          kotlin                15        
20          gradle                7         
21          bazel                 7         
22          git                   8         
23          svn                   8         

У одній таблиці є всі завдання та їх підзавдання, які стосуються відповідного батьківського завдання з використанням _id (первинного ключа) та parentId.

напр. ім'я завдання 'java' має _id = 18 і parentId = 15 означає, що 'java' є підзавантаженням _id = 15, який є 'мовою'.

Знову ж таки, "language" має _id = 15 і parentId = 6 означає "мова" - це підзадача _id = 6, яка є "Програмування".

Таке ж «Програмування» є суб-завданням «Розробка програмного забезпечення».

А «розробка програмного забезпечення» є підзадачею null.

тому я вимагаю один запит , який надає вихідні дані, вказані нижче для вхідного_ід_id = 18 (тобто "java"), тобто список батьківських, батьківських батьківських завдань ... у верхній частині для підзадачі.

_id      name              parentId
4    Software Development   null
6    Programing             4
15   language               6
18   java                  15

В даний час я можу взяти цей висновок, використовуючи 4 запиту в циклі.

SELECT _id,name,parentId FROM task WHERE _id = 18

у наступному iteration _id буде значення parentId з виводу вищезазначеного запиту

що забирає багато часу, тому ми можемо мати краще рішення для цього.

1
додано Автор Kling Klang, джерело
додано Автор Kling Klang, джерело
додано Автор Kling Klang, джерело
Відповідь - це CTE (загальний табличний вираз). Перевірте оператор WITH. sqlite.org/lang_with.html Це поширений спосіб запиту деревоподібних структур у SQL (що в основному є що у вас є)
додано Автор Gabe Sechan, джерело
Відповідь - це CTE (загальний табличний вираз). Перевірте оператор WITH. sqlite.org/lang_with.html Це поширений спосіб запиту деревоподібних структур у SQL (що в основному є що у вас є)
додано Автор Gabe Sechan, джерело

5 Відповіді

Щоб піднятися на дереві, потрібний рекурсивний загальний вираз таблиці

WITH RECURSIVE parents(id, name, parentid, level) AS (
  SELECT _id, name, parentid, 1
  FROM Task
  WHERE _id = 18

  UNION ALL

  SELECT Task._id, Task.name, Task.parentid, level + 1
  FROM Task
  JOIN parents ON Task._id = parents.parentid
)
SELECT id, name, parentid
FROM parents
ORDER BY level DESC;

Це не підтримується до Android Lollipop (рівень API 21).

1
додано
На жаль, умова приєднання було неправильним ...
додано Автор CL., джерело
Підтримка 'WITH' з sqlite 3.8.3 або пізнішої версії
додано Автор Huỳnh Ngọc Bang, джерело
Дякуємо за відповідь! Я отримую вихід з вище запиту 18 | java | 15 замість бажаного виходу. Ваш підхід здається писати, але все ще щось відсутня!
додано Автор Kevan, джерело
Велике спасибі за вашу добру допомогу !!! Працює відмінно. :)
додано Автор Kevan, джерело

Щоб піднятися на дереві, потрібний рекурсивний загальний вираз таблиці

WITH RECURSIVE parents(id, name, parentid, level) AS (
  SELECT _id, name, parentid, 1
  FROM Task
  WHERE _id = 18

  UNION ALL

  SELECT Task._id, Task.name, Task.parentid, level + 1
  FROM Task
  JOIN parents ON Task._id = parents.parentid
)
SELECT id, name, parentid
FROM parents
ORDER BY level DESC;

Це не підтримується до Android Lollipop (рівень API 21).

1
додано
На жаль, умова приєднання було неправильним ...
додано Автор CL., джерело
Підтримка 'WITH' з sqlite 3.8.3 або пізнішої версії
додано Автор Huỳnh Ngọc Bang, джерело
Дякуємо за відповідь! Я отримую вихід з вище запиту 18 | java | 15 замість бажаного виходу. Ваш підхід здається писати, але все ще щось відсутня!
додано Автор Kevan, джерело
Велике спасибі за вашу добру допомогу !!! Працює відмінно. :)
додано Автор Kevan, джерело

Щоб піднятися на дереві, потрібний рекурсивний загальний вираз таблиці

WITH RECURSIVE parents(id, name, parentid, level) AS (
  SELECT _id, name, parentid, 1
  FROM Task
  WHERE _id = 18

  UNION ALL

  SELECT Task._id, Task.name, Task.parentid, level + 1
  FROM Task
  JOIN parents ON Task._id = parents.parentid
)
SELECT id, name, parentid
FROM parents
ORDER BY level DESC;

Це не підтримується до Android Lollipop (рівень API 21).

1
додано
На жаль, умова приєднання було неправильним ...
додано Автор CL., джерело
Підтримка 'WITH' з sqlite 3.8.3 або пізнішої версії
додано Автор Huỳnh Ngọc Bang, джерело
Дякуємо за відповідь! Я отримую вихід з вище запиту 18 | java | 15 замість бажаного виходу. Ваш підхід здається писати, але все ще щось відсутня!
додано Автор Kevan, джерело
Велике спасибі за вашу добру допомогу !!! Працює відмінно. :)
додано Автор Kevan, джерело

У мене також є такі справи, і я об'єднаю sql з Java кодом для вирішення цієї проблеми. Просто щось подібне:

    public ArrayList getRecursiveReverse(String parentId) throws Exception {
    StringBuffer  sqlObject = new StringBuffer();
    sqlObject.append("SELECT T.TABLE_ID ");
    sqlObject.append("FROM   TABLE_NAME T ");
    sqlObject.append("WHERE  1 = 1 ");
    sqlObject.append("       AND T.STATUS = 1 ");
    sqlObject.append("       AND T.PARENT_ID = ? ");

    Cursor c = null;
    String[] params = { parentId };
    ArrayList listIdArray = new ArrayList();
    if (!StringUtil.isNullOrEmpty(parentId)) { 
            listIdArray.add(parentId);
    }
    try {
        c = rawQuery(sqlObject.toString(), params);
        if (c != null) {
            if (c.moveToFirst()) {
                do {
                    String tableId = CursorUtil.getString(c, "TABLE_ID");

                    ArrayList tempArray = getShopRecursiveReverse(tableId);
                    listIdArray.addAll(tempArray);
                } while (c.moveToNext());
            }
        }
    } finally {
        try {
            if (c != null) {
                c.close();
            }
        } catch (Exception e) {
            MyLog.w(getTAG(), GlobalUtil.getCurrentMethodName(), e);
        }
    }
    return listIdArray;
}
0
додано
І з sqlite версії 3.8.3 підтримуємо WITH. Можливо, ви можете скористатися за допомогою пункту "WITH"
додано Автор Huỳnh Ngọc Bang, джерело

У мене також є такі справи, і я об'єднаю sql з Java кодом для вирішення цієї проблеми. Просто щось подібне:

    public ArrayList getRecursiveReverse(String parentId) throws Exception {
    StringBuffer  sqlObject = new StringBuffer();
    sqlObject.append("SELECT T.TABLE_ID ");
    sqlObject.append("FROM   TABLE_NAME T ");
    sqlObject.append("WHERE  1 = 1 ");
    sqlObject.append("       AND T.STATUS = 1 ");
    sqlObject.append("       AND T.PARENT_ID = ? ");

    Cursor c = null;
    String[] params = { parentId };
    ArrayList listIdArray = new ArrayList();
    if (!StringUtil.isNullOrEmpty(parentId)) { 
            listIdArray.add(parentId);
    }
    try {
        c = rawQuery(sqlObject.toString(), params);
        if (c != null) {
            if (c.moveToFirst()) {
                do {
                    String tableId = CursorUtil.getString(c, "TABLE_ID");

                    ArrayList tempArray = getShopRecursiveReverse(tableId);
                    listIdArray.addAll(tempArray);
                } while (c.moveToNext());
            }
        }
    } finally {
        try {
            if (c != null) {
                c.close();
            }
        } catch (Exception e) {
            MyLog.w(getTAG(), GlobalUtil.getCurrentMethodName(), e);
        }
    }
    return listIdArray;
}
0
додано
І з sqlite версії 3.8.3 підтримуємо WITH. Можливо, ви можете скористатися за допомогою пункту "WITH"
додано Автор Huỳnh Ngọc Bang, джерело
android_jobs_ua
android_jobs_ua
120 учасників

Публикуем вакансии и запросы на поиск работы по направлению Android. Здесь всё: full-time, part-time, remote и разовые подработки.

Mobile Dev Jobs UA
Mobile Dev Jobs UA
20 учасників

Публикуем вакансии и запросы на поиск работы по направлению iOS, Android, Xamarin, RN и т.д.