使用CAST在XML上进行区分

时间:2018-12-20 06:05:10

标签: sql postgresql join distinct

我有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 :(得分:1)

您显示的查询与表样本中的逻辑不匹配。这将:

Popen.subprocess()

您的问题中没有任何内容可以保证使用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