如何将MSSQL CTE查询转换为MySQL?

时间:2012-01-12 10:29:46

标签: mysql sql-server common-table-expression adjacency-list

在我的MySQL架构中,我有category(id, parentid, name)

在MSSQL中,我有CTE查询(从下到上为所提供的类别ID构建一个类别树:

with CTE (id, pid, name) 
as
(
    select id, parentid as pid,name
    from category
    where id = 197
      union all
        select CTE.pid as id , category.parentid as pid, category.name
        from CTE 
          inner join category 
            on category.id = CTE.pid
 )
 select * from CTE 

如何将该查询“转换”为MySQL?

4 个答案:

答案 0 :(得分:32)

不幸的是,MySQL不支持CTE(公用表表达式)。这是早就应该的IMO。通常,您可以只使用子查询,但此特定CTE 递归:它在查询中引用自身。递归CTE对于分层数据非常有用,但同样重要:MySql根本不支持它们。您必须实现存储过程才能获得相同的结果。

我之前的答案应该提供一个很好的起点:

  

Generating Depth based tree from Hierarchical Data in MySQL (no CTEs)

答案 1 :(得分:3)

值得庆幸的是,不再需要了,因为MySQL从8.0.1 supports CTE开始。

答案 2 :(得分:0)

不幸的是,MYSQl或XAMPP(MARIADB)mysql不支持CTE(COMMON TABLE EXPRESSIONS), 同样,您将必须使用嵌套查询。

有关更多信息,请单击以下链接:-

https://mariadb.com/kb/en/library/with/

答案 3 :(得分:0)

请检查您使用的是哪个版本的 MySQL SELECT VERSION(); 如果是 8 或以上,您可以继续我的评论。 在 MySQL 8.0、MariaDB 10.2 及更高版本中,您可以使用递归 CTE:

WITH RECURSIVE CTE (id, pid, name) AS (
    select id, parentid as pid,name
from category
where id = 197
  union all
    select CTE.pid as id , category.parentid as pid, category.name
    from CTE 
      inner join category 
        on category.id = CTE.pid
)
select * from CTE ;

请注意,CTE 在 MySQL 中受 cte_max_recursion_depth(默认为 1000,最大为 4,294,967,295 (2³²−1))和在 MariaDB 中受 max_recursive_iterations(默认为 4,294,967,295)的限制。

您可以通过执行来增加限制:

SET cte_max_recursion_depth = 4294967295;

它只会影响您当前的会话,不会持久化。