Cleaner SQL CTE than the current one

﹥>﹥吖頭↗ 提交于 2021-02-11 18:23:30

问题


Currently I use the following CTE to grab a category and any category below it:

WITH RECURSIVE tree AS (
SELECT * FROM (
    SELECT categoryId, 
          categoryName, 
          categoryParentId,
          categoryDescr,
          categoryType,
          categoryDC,
          categoryLedgerId,
          1 as categoryDepth
    FROM tbl_categories
    WHERE categoryId = '.$categoryId.'
    UNION
    SELECT categoryId, 
          categoryName, 
          categoryParentId,
          categoryDescr,
          categoryType,
          categoryDC,
          categoryLedgerId,
          1 as categoryDepth
    FROM tbl_categories_custom
    WHERE categoryId = '.$categoryId.'
) AS combined

UNION ALL

SELECT p.categoryId,
        p.categoryName,
        p.categoryParentId,
        p.categoryDescr,
        p.categoryType,
        p.categoryDC,
        p.categoryLedgerId, 
        t.categoryDepth + 1
        FROM (
           SELECT * FROM tbl_categories
           UNION
           SELECT * FROM tbl_categories_custom
        ) AS p
        JOIN tree t ON t.categoryId = p.categoryParentId
)
SELECT *
FROM tree

However, as @trincot showed me in Union two tables with categories in a query that retrieves categories and its parents it can be done much cleaner.

His version over there grabs a category and any category above it.

This one should do it the opposite way; grab any category and any category below it. Which it does. But it seems overcomplicated now that I read his other version.

How to simplify this CTE?


回答1:


Indeed, you can make this shorter by first making a common table expression for the union, and only then doing the recursive one.

The query is quite similar to the one posted in the other question. The major change is that the join condition in the inner join ... on clause is now reversed. The = 1 part is where you would do the comparison with your PHP variable:

with recursive 
base as (
    select * from tbl_categories
    union
    select * from tbl_categories_custom
),
cte as (
    select 1 as categoryDepth,
           base.* 
    from   base
    where  categoryId = 1
    union
    select cte.categoryDepth + 1, 
           base.*
    from   cte
    inner join base
            on cte.categoryId = base.categoryParentId
)
select   *
from     cte;


来源:https://stackoverflow.com/questions/65687860/cleaner-sql-cte-than-the-current-one

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!