#sql #sql-server
#sql #sql-сервер
Вопрос:
У меня есть 2 таблицы
1. parent table and 2. Child Table
Значение родительской таблицы
Pid parent_name
1 A
2 B
3 D
4 H
5 J
Значение дочерней таблицы
Chid Pid child_name
1 1 B
2 1 C
3 1 D
4 2 F
5 2 G
6 3 H
7 3 I
8 4 J
9 4 K
10 5 L
когда я введу ввод A, я получу вывод в виде
Pid
B
D
H
J
когда я введу ввод D, я получу вывод в виде
Pid
H
J
Похоже на древовидную структуру, когда я даю родительское имя, результатом будут все дочерние элементы, внуки, внучатые дочерние элементы….
все родительские элементы, имеющие дочерний
Ответ №1:
Вам нужно использовать рекурсивный CTE для вашей цели.
DECLARE @Id varchar(10)='your_pid'
;WITH cte AS
(
SELECT b.pid, b.chid, b.parent_name
FROM parent a inner join child b on b.pid= a.pid
WHERE b.pid = @Id
UNION ALL
SELECT b.pid
FROM parent a inner join child b on b.pid= a.pid
inner join cte on cte.pid= b.chid
WHERE b.pid = @Id )
SELECT parent_name
FROM cte
Ответ №2:
Я полагаю, вам нужно будет сохранить родительские дочерние записи в одной таблице следующим образом:
1 NULL A
2 1 B
3 1 C
4 1 D
5 2 F
6 2 G
7 4 H
8 4 I
9 7 J
10 7 K
11 9 L
Затем вы можете запросить данные следующим образом:
WITH T (id, pid, name) AS (
SELECT 1, NULL, 'A'
UNION ALL
SELECT 2, 1, 'B'
UNION ALL
SELECT 3, 1, 'C'
UNION ALL
SELECT 4, 1, 'D'
UNION ALL
SELECT 5, 2, 'F'
UNION ALL
SELECT 6, 2, 'G'
UNION ALL
SELECT 7, 4, 'H'
UNION ALL
SELECT 8, 4, 'I'
UNION ALL
SELECT 9, 7, 'J'
UNION ALL
SELECT 10, 7, 'K'
UNION ALL
SELECT 11, 9, 'L'
), U AS (
SELECT B.* FROM T A JOIN T B ON B.pid = A.id JOIN T C ON C.pid = B.id WHERE A.name = 'A'
UNION ALL
SELECT P.* FROM T P JOIN U Q ON Q.id = P.pid JOIN T R ON R.pid = P.id
)
SELECT DISTINCT name FROM U
Например, если ваша таблица называется «tbl», то:
WITH T (id, pid, name) AS (
SELECT id, pid, name FROM tbl
), U AS (
SELECT B.* FROM T A JOIN T B ON B.pid = A.id JOIN T C ON C.pid = B.id WHERE A.name = 'A'
UNION ALL
SELECT P.* FROM T P JOIN U Q ON Q.id = P.pid JOIN T R ON R.pid = P.id
)
SELECT DISTINCT name FROM U