cte sql 到 JPA 的简单子集查询

Posted

技术标签:

【中文标题】cte sql 到 JPA 的简单子集查询【英文标题】:cte sql to simple subset query for JPA 【发布时间】:2019-07-20 05:35:29 【问题描述】:

我们如何将下面的 CTE 查询(递归)更改为简单的子集 sql:

  WITH links (parent, child) AS
  ( SELECT parent, child
        FROM Heirarchy_Table
        WHERE parent = '111111'
   UNION ALL 
    SELECT ht.parent, ht.child
        FROM Heirarchy_Table ht
        INNER JOIN links ON links.child = ht.parent)
SELECT * FROM links fl;

我需要将此查询用于 JPA,因为 JPA 未处理“WITH”子句。 [注意:“链接”cte 是递归使用的]。 非常感谢!!

【问题讨论】:

***.com/questions/52990198/… 谢谢肖恩,但我知道 JPA 没有处理“WITH”子句。此外,在上面的查询中,我们使用递归。所以,SELECT * from (SELECT * ...) 对我不起作用。 不做递归就不能做递归。因此,将其移至子查询或任何不起作用的东西。处理这个问题的最好方法是创建一个存储过程并从 JPA 中调用它。 是的,有道理。我试图避免存储过程。但是,这看起来是一个不错的解决方法。非常感谢!! 【参考方案1】:

我们如何将下面的 CTE 查询(递归)更改为简单的子集 sql:

创建一个视图。

create view links
as
WITH links (parent, child) AS
( SELECT parent, child
    FROM Heirarchy_Table
    WHERE parent = '111111'
UNION ALL 
SELECT ht.parent, ht.child
    FROM Heirarchy_Table ht
    INNER JOIN links ON links.child = ht.parent)
SELECT * FROM links fl;

然后就可以查询视图了

select * from links

或者您可以使用内联表值函数,有时称为“参数化视图”,如下所示:

create or alter function GetLinks(@parent int)
returns table
as 
return
WITH links (parent, child) AS
(SELECT parent, child
    FROM Heirarchy_Table
    WHERE parent = @parent
UNION ALL 
SELECT ht.parent, ht.child
    FROM Heirarchy_Table ht
    INNER JOIN links ON links.child = ht.parent)
SELECT * FROM links fl;

你可以像这样查询:

select * from GetLinks(1111)

【讨论】:

这里,“WHERE parent = '111111'”在运行时获得价值,这也在 CTE 内部。所以,我认为,视图不是一个好的选择。 谢谢大卫。这看起来是个不错的选择。我不知道 MsSql 中有这个功能。【参考方案2】:
@Query(value = "WITH RECURSIVE domainCTE AS (" +
        "   SELECT *, " +
        "       id AS root " +
        "       FROM domain " +
        "       WHERE parent IS NULL " +
        "   UNION ALL " +
        "       SELECT domain.*, " +
        "           domainCTE.root " +
        "       FROM domain " +
        "       JOIN domainCTE ON domain.parent = domainCTE.id " +
        ") " +
        "SELECT DISTINCT d.id, d.name, d.parent FROM domain d " +
        "    JOIN domainCTE cte " +
        "    ON d.id = cte.root " +
        "    WHERE cte.id IN :domainIds",
        nativeQuery = true
)
List<Domain> findDomainRootsByDomainIds(List<Long> domainIds);

【讨论】:

欢迎来到 SO。请在代码中添加相关描述,以更好地理解您的答案。 SO 不推荐纯代码答案。

以上是关于cte sql 到 JPA 的简单子集查询的主要内容,如果未能解决你的问题,请参考以下文章

是否有 JPA / JPQL 查询来搜索春季作为 JSON 传递的实体子集?

JPA双向实体:在查询父实体时仅选择子实体的子集

SQL Server 公用表表达式(CTE)实现递归

SQL Server 公用表表达式(CTE)实现递归

sql子集查询

sql 怎么根据父id查询下三级子集