【问题标题】:Implement Recursive CTE for Hierarchical Query to MariaDB为 MariaDB 的分层查询实现递归 CTE
【发布时间】:2019-06-20 23:25:19
【问题描述】:

我有这张表,我想存储一个记录链。

CREATE TABLE table_name (
    id INT,
    unique_id varchar,
    reference_id varchar,
);

我想为 MariDB 实现 SQL 查询,该查询通过 unique_id 和所有记录 reference_id 打印所有记录。像这样的:

| id | unique_id | reference_id |   |   |
|----|-----------|--------------|---|---|
| 43 | 55544     |              |   |   |
| 45 | 45454     | 43           |   |   |
| 66 | 55655     | 45           |   |   |
| 78 | 88877     | 66           |   |   |
| 99 | 454       | 33           |   |   |

我希望当我选择记录 55544 来获取所有交易时,因为彼此都使用指向它们的 id。我如何使用递归 CTE 来实现这一点?有没有更好的办法?

unique_id 55544 记录的预期结果:

| id | unique_id | reference_id |   |   |
|----|-----------|--------------|---|---|
| 43 | 55544     |              |   |   |
| 45 | 45454     | 43           |   |   |
| 66 | 55655     | 45           |   |   |
| 78 | 88877     | 66           |   |   |

如何在 HQL 中也实现此查询?我想在 JPA 中使用它?

【问题讨论】:

  • 我想完整的答案是不可能的,因为:How this query can be implemented also in HQL?。如果我错了,请纠正我,但 HQL 不支持所有类型的 CTE,并且无法实现递归查询。 NamedQuery/NamedNativeQuery - IDK 可能有一些“聪明”的技巧。
  • 这个查询可以用 JPA 重写吗? stackoverflow.com/a/54394019/1103606
  • 您可以通过 JPA 运行本机 SQL。关于 JPQL - 我想不是。
  • reference_idid 的数据类型应该相同,而不是类型不匹配(INT 与 VARCHAR)

标签: sql jpa mariadb jpa-2.0 recursive-query


【解决方案1】:

您可以使用递归 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;

【讨论】:

  • 如何使用参考 ID 获取所有记录?目前我只得到以下记录:db-fiddle.com/f/sMQvdieGxZA3RB548qPS68/0
  • @PeterPenzov 将on cte.id = t.reference_id 更改为on cte.reference_id = t.id
  • 这是一段绝对漂亮且超级有用的 SQL。非常感谢你,戈登!
【解决方案2】:

以下查询应该符合您的预期。这是一个递归查询,它依赖于一个变量来通过依赖树来跟踪父子关系。

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

demo on DB Fiddle 产生:

|编号 |唯一标识 |参考ID | | --- | --------- | ------------ | | 45 | 45454 | 43 | | 66 | 55655 | 45 | | 78 | 88877 | 66 |

PS:请注意,这不会返回最上面的父行。如果您也需要它,您可以将WHERE 条件更改为:

where reference_id=@ref or unique_id = 55544

【讨论】:

  • 我需要问额外的问题。发送 id 66 时如何获取所有行?
  • 谢谢,这似乎在 MySQL 5 上也有效。我想知道是否有办法扭转它,并将 ID 从 78 提高到 66、45 和 43
猜你喜欢
  • 1970-01-01
  • 2015-01-09
  • 2014-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-25
  • 2017-05-11
相关资源
最近更新 更多