Sql 实现递归CTE实现对MariaDB的分层查询
我有这个表,我想存储一个记录链Sql 实现递归CTE实现对MariaDB的分层查询,sql,jpa,mariadb,jpa-2.0,recursive-query,Sql,Jpa,Mariadb,Jpa 2.0,Recursive Query,我有这个表,我想存储一个记录链 CREATE TABLE table_name ( id INT, unique_id varchar, reference_id varchar, ); 我想为MariDB实现SQL查询,该查询通过唯一的\u id和所有记录引用\u id打印所有记录。类似如下: | id | unique_id | reference_id | | | |----|-----------|--------------|---|---| | 43
CREATE TABLE table_name (
id INT,
unique_id varchar,
reference_id varchar,
);
我想为MariDB实现SQL查询,该查询通过唯一的\u id和所有记录引用\u id打印所有记录。类似如下:
| id | unique_id | reference_id | | |
|----|-----------|--------------|---|---|
| 43 | 55544 | | | |
| 45 | 45454 | 43 | | |
| 66 | 55655 | 45 | | |
| 78 | 88877 | 66 | | |
| 99 | 454 | 33 | | |
我希望在选择Record55544时获取所有事务,因为每个事务都使用指向它们的id。如何使用递归CTE实现这一点?有更好的办法吗
具有唯一\u id 55544的记录的预期结果:
| id | unique_id | reference_id | | |
|----|-----------|--------------|---|---|
| 43 | 55544 | | | |
| 45 | 45454 | 43 | | |
| 66 | 55655 | 45 | | |
| 78 | 88877 | 66 | | |
如何在HQL中实现此查询?我想在JPA中使用它?下面的查询应该满足您的期望。这是一个递归查询,依赖于一个变量通过依赖关系树跟踪父子关系
select @ref:=id as id, unique_id, reference_id
from mytable
join (select @ref:=id from mytable WHERE unique_id = 55544)tmp
where reference_id=@ref
这将产生:
| id | unique_id | reference_id |
| --- | --------- | ------------ |
| 45 | 45454 | 43 |
| 66 | 55655 | 45 |
| 78 | 88877 | 66 |
您可以使用递归CTE。这是正确的方法:
with recursive cte as (
select t.*
from table_name t
where t.unique_id = 55544
union all
select t.*
from cte join
table_name t
on cte.id = t.reference_id
)
select *
from cte;
我认为完整的答案是不可能的,因为:
这个查询如何也可以在HQL中实现?
。如果我错了,请纠正我,但HQL不支持所有类型的CTE,并且无法实现递归查询。也许使用NamedQuery/NamedNativeQuery-IDK会有一些“聪明”的技巧。这个查询可以用JPA重写吗?您可以通过JPA运行本机SQL。关于JPQL-我想不是。您应该拥有与reference\u id
和id
相同的数据类型。您没有类型不匹配(INT vs VARCHAR),我需要问另外的问题。当我发送id 66时,如何获取所有行?谢谢,这似乎在MySQL5上也有效。我想知道是否有一种方法可以逆转它,将id从78提高到66、45和43。我如何才能使用参考id上下获取所有记录?目前我只得到以下记录:@PeterPenzov changeon cte.id=t.reference\u id
到on cte.reference\u id=t.id
这是一个非常漂亮和非常有用的SQL语句。非常感谢你,戈登@哈特利山。非常感谢。
with recursive cte as (
select t.*
from table_name t
where t.unique_id = 55544
union all
select t.*
from cte join
table_name t
on cte.id = t.reference_id
)
select *
from cte;