Sqlite限制重复行具有相同的ID
Sqlite limit repeated rows with same id
我正在使用 android SQLite 数据库,结果如下:
id | root_id | parent_id |name
----------------------------------
613 | null | null | m1
612 | null | null | m4
570 | null | null | m1
635 | 570 | 570 | m6
653 | 570 | 635 | m1
652 | 570 | 635 | m3
632 | 570 | 570 | m9
392 | null | null | m2
753 | 392 | 392 | m5
751 | 392 | 392 | m4
391 | null | null | m7
我通过以下查询得到了这个结果:
WITH RECURSIVE all_employees(id, root_id, parent_id, name) AS (
SELECT id, id AS root_id, parent_id, name FROM employees WHERE parent_id IS NULL
UNION ALL
SELECT c.id, (CASE WHEN c.parent_id IS NOT NULL THEN p.root_id END), c.parent_id, c.name FROM employees c JOIN all_employees p ON p.id = c.parent_id ORDER BY id DESC
)
SELECT id, (CASE WHEN id != root_id THEN root_id ELSE NULL END) root_id, parent_id, name FROM all_employees
我想为具有相同root_id的重复行设置一个限制,例如:
使用 root_id 570 加载 2 行,使用 root_id 392 加载 1 行:
id | root_id | parent_id |name
----------------------------------
613 | null | null | m1
612 | null | null | m4
570 | null | null | m1
635 | 570 | 570 | m6
653 | 570 | 635 | m1
392 | null | null | m2
753 | 392 | 392 | m5
391 | null | null | m7
有限选择联合
WITH RECURSIVE all_employees(id, root_id, parent_id, name) AS (
SELECT id, id AS root_id, parent_id, name
FROM employees
WHERE parent_id IS NULL
UNION ALL
SELECT c.id, (CASE WHEN c.parent_id IS NOT NULL THEN p.root_id END), c.parent_id, c.name
FROM employees c
JOIN all_employees p ON p.id = c.parent_id ORDER BY id DESC
)
SELECT id, root_id, parent_id, name
FROM all_employees
where root_id not in (570, 392)
union all
select *
from (
select *
from all_employees
where root_id =570
limit 3
)
union all
select *
from (
select *
from all_employees
where root_id =392
limit 2
)
创建另一个 CTE
:
counters(root_id, n) AS (VALUES (570, 2), (392, 1))
你 return 所有 root_id
想要限制它们的行和每个行的行数然后使用递归 [=] 的 LEFT
连接12=] 到那个。
最后,在 WHERE
子句中设置带有相关子查询的条件:
WITH
RECURSIVE all_employees(id, root_id, parent_id, name) AS (
SELECT id, id AS root_id, parent_id, name
FROM employees
WHERE parent_id IS NULL
UNION ALL
SELECT c.id, (CASE WHEN c.parent_id IS NOT NULL THEN p.root_id END), c.parent_id, c.name
FROM employees c JOIN all_employees p
ON p.id = c.parent_id
),
counters(root_id, n) AS (VALUES (570, 2), (392, 1))
SELECT a.id, (CASE WHEN a.id <> a.root_id THEN a.root_id END) root_id, a.parent_id, a.name
FROM all_employees a LEFT JOIN counters c
ON c.root_id = a.root_id
WHERE c.root_id IS NULL
OR (SELECT COUNT(*) FROM all_employees b WHERE b.root_id IS a.root_id AND b.id <= a.id) <= c.n
请注意 CTE
中的 ORDER BY
子句是无用的,因为当您 select来自 CTE
.
您可以在最终查询中设置所需行的顺序。
向 CTE 添加计数器,然后使用 WHERE
逻辑进行过滤:
WITH RECURSIVE all_employees(id, root_id, parent_id, name, lev) AS (
SELECT id, id AS root_id, parent_id, name, 0 as lev
FROM employees
WHERE parent_id IS NULL
UNION ALL
SELECT c.id,
(CASE WHEN c.parent_id IS NOT NULL THEN p.root_id END), c.parent_id, c.name, p.lev + 1
FROM employees c JOIN
all_employees p
ON p.id = c.parent_id
ORDER BY id DESC -- don't think this does anything
)
SELECT id, (CASE WHEN id <> root_id THEN root_id END) as root_id, parent_id, name
FROM all_employees
WHERE root_id = 570 AND cnt <= 1 OR
root_id = 392 AND cnt <= 2 OR
root_id NOT IN (570, 392);
这里的重点是将计数放入递归 CTE,然后使用该信息进行过滤。您可以根据自己的喜好对 WHERE
子句进行措辞:
WHERE (CASE WHEN root_id = 570 THEN cnt <= 1
WHEN root_id = 392 THEN cnt <= 2
ELSE 1
END)
我正在使用 android SQLite 数据库,结果如下:
id | root_id | parent_id |name
----------------------------------
613 | null | null | m1
612 | null | null | m4
570 | null | null | m1
635 | 570 | 570 | m6
653 | 570 | 635 | m1
652 | 570 | 635 | m3
632 | 570 | 570 | m9
392 | null | null | m2
753 | 392 | 392 | m5
751 | 392 | 392 | m4
391 | null | null | m7
我通过以下查询得到了这个结果:
WITH RECURSIVE all_employees(id, root_id, parent_id, name) AS (
SELECT id, id AS root_id, parent_id, name FROM employees WHERE parent_id IS NULL
UNION ALL
SELECT c.id, (CASE WHEN c.parent_id IS NOT NULL THEN p.root_id END), c.parent_id, c.name FROM employees c JOIN all_employees p ON p.id = c.parent_id ORDER BY id DESC
)
SELECT id, (CASE WHEN id != root_id THEN root_id ELSE NULL END) root_id, parent_id, name FROM all_employees
我想为具有相同root_id的重复行设置一个限制,例如: 使用 root_id 570 加载 2 行,使用 root_id 392 加载 1 行:
id | root_id | parent_id |name
----------------------------------
613 | null | null | m1
612 | null | null | m4
570 | null | null | m1
635 | 570 | 570 | m6
653 | 570 | 635 | m1
392 | null | null | m2
753 | 392 | 392 | m5
391 | null | null | m7
有限选择联合
WITH RECURSIVE all_employees(id, root_id, parent_id, name) AS (
SELECT id, id AS root_id, parent_id, name
FROM employees
WHERE parent_id IS NULL
UNION ALL
SELECT c.id, (CASE WHEN c.parent_id IS NOT NULL THEN p.root_id END), c.parent_id, c.name
FROM employees c
JOIN all_employees p ON p.id = c.parent_id ORDER BY id DESC
)
SELECT id, root_id, parent_id, name
FROM all_employees
where root_id not in (570, 392)
union all
select *
from (
select *
from all_employees
where root_id =570
limit 3
)
union all
select *
from (
select *
from all_employees
where root_id =392
limit 2
)
创建另一个 CTE
:
counters(root_id, n) AS (VALUES (570, 2), (392, 1))
你 return 所有 root_id
想要限制它们的行和每个行的行数然后使用递归 [=] 的 LEFT
连接12=] 到那个。
最后,在 WHERE
子句中设置带有相关子查询的条件:
WITH
RECURSIVE all_employees(id, root_id, parent_id, name) AS (
SELECT id, id AS root_id, parent_id, name
FROM employees
WHERE parent_id IS NULL
UNION ALL
SELECT c.id, (CASE WHEN c.parent_id IS NOT NULL THEN p.root_id END), c.parent_id, c.name
FROM employees c JOIN all_employees p
ON p.id = c.parent_id
),
counters(root_id, n) AS (VALUES (570, 2), (392, 1))
SELECT a.id, (CASE WHEN a.id <> a.root_id THEN a.root_id END) root_id, a.parent_id, a.name
FROM all_employees a LEFT JOIN counters c
ON c.root_id = a.root_id
WHERE c.root_id IS NULL
OR (SELECT COUNT(*) FROM all_employees b WHERE b.root_id IS a.root_id AND b.id <= a.id) <= c.n
请注意 CTE
中的 ORDER BY
子句是无用的,因为当您 select来自 CTE
.
您可以在最终查询中设置所需行的顺序。
向 CTE 添加计数器,然后使用 WHERE
逻辑进行过滤:
WITH RECURSIVE all_employees(id, root_id, parent_id, name, lev) AS (
SELECT id, id AS root_id, parent_id, name, 0 as lev
FROM employees
WHERE parent_id IS NULL
UNION ALL
SELECT c.id,
(CASE WHEN c.parent_id IS NOT NULL THEN p.root_id END), c.parent_id, c.name, p.lev + 1
FROM employees c JOIN
all_employees p
ON p.id = c.parent_id
ORDER BY id DESC -- don't think this does anything
)
SELECT id, (CASE WHEN id <> root_id THEN root_id END) as root_id, parent_id, name
FROM all_employees
WHERE root_id = 570 AND cnt <= 1 OR
root_id = 392 AND cnt <= 2 OR
root_id NOT IN (570, 392);
这里的重点是将计数放入递归 CTE,然后使用该信息进行过滤。您可以根据自己的喜好对 WHERE
子句进行措辞:
WHERE (CASE WHEN root_id = 570 THEN cnt <= 1
WHEN root_id = 392 THEN cnt <= 2
ELSE 1
END)