Отличается от XML с CAST - PullRequest
       18

Отличается от XML с CAST

0 голосов
/ 20 декабря 2018

у меня 4 таблицы.Таблица не содержит ссылки foreign key, где имя имеет тип xml

t1:

| id  | name           |
+-----+----------------+
| a1  | <ID>a1<ID>     |
| a2  | <ID>a2<ID>     |
| a3  | <ID>a3<ID>     |

t2:

| id  | name        |   t1_id      |
+-----+-------------+--------------+
| b1  | <ID>b1<ID>  | a1           |
| b2  | <ID>b2<ID>  | a2           |
| b3  | <ID>b3<ID>  | a3           |
| b4  | <ID>b4<ID>  | a1           |

t3:

| id  | name        |   t2_id      |
+-----+-------------+--------------+
| c1  | <ID>c1<ID>  | b1           |
| c2  | <ID>c2<ID>  | b2           |
| c3  | <ID>c3<ID>  | b3           |

t4:

| id  | name        |   t3_id      |
+-----+-------------+--------------+
| d1  | <ID>d1<ID>  | c2           |
| d2  | <ID>d2<ID>  | c3           |

Мне нужно получить все связанные данные.Когда я указываю 'a1', я ожидаю что-то вроде

| name         | name        |   name       |   name       |
+--------------+-------------+--------------+--------------+
| <ID>a1<ID>   | <ID>b1<ID>  | <ID>c1<ID>   |              |
|              | <ID>b4<ID>  |              |              |

Полученный результат:

| name         | name        |   name       |   name       |
+--------------+-------------+--------------+--------------+
| <ID>a1<ID>   | <ID>b1<ID>  | <ID>c1<ID>   |              |
| <ID>a1<ID>   | <ID>b4<ID>  |              |              |

Чтобы решить эту проблему, я использовал

SELECT DISTINCT CAST (a.name AS TEXT), CAST (b.name AS TEXT), CAST (c.name AS TEXT), CAST (d.name AS TEXT)
FROM t1 AS a

LEFT JOIN t2 AS b
ON b.id = 
CAST((xpath('/ID/text()', b.name))[1] AS TEXT) 

LEFT JOIN t3 AS c
ON c.id = 
CAST((xpath('/ID/text()', c.name))[1] AS TEXT) 

LEFT JOIN t4 AS d
ON d.id = 
CAST((xpath('/ID/text()', d.name))[1] AS TEXT) 

Вышене работает.Как решить это.Это оптимизированный запрос?Я пробовал вложенные запросы.Там возникает проблема Distinct

Каков наилучший и оптимизированный способ для достижения этой цели?Используя JOIN или Nested query?

1 Ответ

0 голосов
/ 20 декабря 2018

Отображаемый вами запрос не соответствует логике в примерах таблицы.Это будет:

SELECT t1.name::text, t2.name::text, t3.name::text, t4.name::text
FROM   t1
LEFT   JOIN t2 b ON t2.t1_id = t1.id
LEFT   JOIN t3 c ON t3.t2_id = t2.id
LEFT   JOIN t4 d ON t4.t3_id = t3.id
WHERE  t1.id = 'a1';

И ничего в вашем вопросе не гарантирует использование DISTINCT.

Если вы действительно хотите скрыть повторяющиеся имена в том же столбце упорядоченного списка, как показано:

SELECT CASE WHEN rn1 = 1 THEN name1 END AS name1
     , CASE WHEN rn2 = 1 THEN name2 END AS name2
     , CASE WHEN rn3 = 1 THEN name3 END AS name3
     , CASE WHEN rn4 = 1 THEN name4 END AS name4
FROM  (
   SELECT t1.name::text AS name1, t2.name::text AS name2, t3.name::text AS name3, t4.name::text AS name4
        , row_number() OVER (PARTITION BY t1.id ORDER ORDER BY t2.id, t3.id, t4.id) AS rn1
        , row_number() OVER (PARTITION BY t1.id, t2.id ORDER ORDER BY t3.id, t4.id) AS rn2
        , row_number() OVER (PARTITION BY t1.id, t2.id, t3.id ORDER ORDER BY t4.id) AS rn3
   FROM   t1
   LEFT   JOIN t2 b ON t2.t1_id = t1.id
   LEFT   JOIN t3 c ON t3.t2_id = t2.id
   LEFT   JOIN t4 d ON t4.t3_id = t3.id
   WHERE  t1.id = 'a1'
   ) sub
ORDER BY t1.id, t2.id, t3.id, t4.id;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...