【问题标题】:How to get all the categories and sub categories in PostgreSQL?如何获取PostgreSQL中的所有类别和子类别?
【发布时间】:2021-03-14 11:45:06
【问题描述】:

我正在使用 .net core 5 与 EF core 和 postgres 10 创建一个小型电子商务演示应用程序。
我正在尝试获取主页上的所有类别和子类别。

这是我的类别层次结构:

男性(父类)

  • 上衣(子类别)
    • 正式衬衫(叶级类别)
    • T 恤(叶级类别)

女性

  • 印度和融合服饰

    • 库尔塔斯和西装
    • 纱丽
  • 鞋类

    • 高跟鞋

这是我的创建表和插入脚本:

CREATE TABLE category
(
    id                uuid      DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL,
    parent_id         uuid                                             NULL,
    name              character varying(255)                           NOT NULL,
    short_description character varying(255)                           NOT NULL,
    activate_on       date                                             NULL,
    deactivate_on     date                                             NULL,
    url_segment       character varying(255)                           NOT NULL,
    meta_keywords     character varying                                NOT NULL,
    meta_description  character varying                                NOT NULL,
    sort_order        integer                                          NOT NULL,
    created_on        timestamp DEFAULT CURRENT_TIMESTAMP,
    created_by        character varying(100),
    modified_on       timestamp DEFAULT CURRENT_TIMESTAMP,
    modified_by       character varying(100),
    is_active         boolean
);



INSERT INTO public.category (id, parent_id, name, short_description, activate_on, deactivate_on, url_segment,
                             meta_keywords, meta_description, sort_order, created_on, created_by, modified_on,
                             modified_by, is_active)
VALUES ('0ca0c27c-f45b-4768-a3cb-958bfbf6df26', '6dfdf5e4-673b-4134-b4a9-3a0b14b50e6a', 'T-Shirts', 'T-Shirts',
        '2021-02-21', NULL, 'men-tshirts',
        't shirt for mens india, t shirt for men online, polo t shirts, sport t shirt, black t shirt, blue t shirt, white t shirt',
        'Men''s T-shirts - Buy T-shirts for men online in India. Choose from a wide range of polo, round, V neck & more Men''s T-shirts in various designs at Myntra.',
        1, '2021-02-21 13:17:15.652506', 'glenn', NULL, '', TRUE);
INSERT INTO public.category (id, parent_id, name, short_description, activate_on, deactivate_on, url_segment,
                             meta_keywords, meta_description, sort_order, created_on, created_by, modified_on,
                             modified_by, is_active)
VALUES ('6927198d-9240-43b0-853a-0507cad3b529', '6dfdf5e4-673b-4134-b4a9-3a0b14b50e6a', 'Formal Shirts',
        'Formal Shirts', '2021-02-21', NULL, 'men-formal-shirts',
        'Men''s formal shirts, formal shirts for men, slim fit formal shirts for men, latest formal shirts for men, formal shirts for men online, formal shirts for men India',
        'Formal Shirts for Men - Shop for trendy men''s formal shirts online in India at Myntra. ✯Free Shipping ✯Easy returns and exchanges ✯COD',
        2, '2021-02-21 13:21:16.125333', 'glenn', NULL, '', TRUE);
INSERT INTO public.category (id, parent_id, name, short_description, activate_on, deactivate_on, url_segment,
                             meta_keywords, meta_description, sort_order, created_on, created_by, modified_on,
                             modified_by, is_active)
VALUES ('0d3f9e43-12a2-4f8c-a008-a45cbf15fedd', NULL, 'Women', 'Women', '2021-02-21', NULL, 'women',
        'women online shopping, online shopping for women, women clothing, women dresses online',
        'Online Shopping for Women. Shop Online from a wide range of womens clothing, shoes, Ladies bags & more in India @ Myntra ✯Free Shipping ✯COD ✯Easy returns and exchanges.',
        0, '2021-02-21 13:26:04.447031', 'glenn', NULL, '', TRUE);
INSERT INTO public.category (id, parent_id, name, short_description, activate_on, deactivate_on, url_segment,
                             meta_keywords, meta_description, sort_order, created_on, created_by, modified_on,
                             modified_by, is_active)
VALUES ('6dfdf5e4-673b-4134-b4a9-3a0b14b50e6a', 'eb81c712-0643-45a2-b597-129a1f9892e2', 'Topwear', 'Topwear',
        '2021-02-21', NULL, 'top-wear', 'mens topwear', 'mens topwear', 1, '2021-02-21 13:12:30.518814', 'glenn',
        NULL, '', TRUE);
INSERT INTO public.category (id, parent_id, name, short_description, activate_on, deactivate_on, url_segment,
                             meta_keywords, meta_description, sort_order, created_on, created_by, modified_on,
                             modified_by, is_active)
VALUES ('eb81c712-0643-45a2-b597-129a1f9892e2', NULL, 'Men', 'Men', '2021-02-21', NULL, 'men',
        'Men Topwear, Men Topwear in India, buy Men Topwear online in india, online store for Men Topwear, Shop online for Men Topwear, online shopping for Men Topwear, Online shopping for Men Topwear in India, reviews and prices',
        'Men Topwear Online. Shop for Men Topwear in India ? Buy latest range of Men Topwear at Myntra ? Free Shipping ? COD ? Easy returns and exchanges',
        0, '2021-02-21 13:10:29.204689', 'glenn', NULL, '', TRUE);
INSERT INTO public.category (id, parent_id, name, short_description, activate_on, deactivate_on, url_segment,
                             meta_keywords, meta_description, sort_order, created_on, created_by, modified_on,
                             modified_by, is_active)
VALUES ('731b01bd-fab7-475e-adb2-6322eb9eac68', '0d3f9e43-12a2-4f8c-a008-a45cbf15fedd', 'India & Fusion Wear',
        'India & Fusion Wear', '2021-02-21', NULL, 'fusion-wear',
        'indo western fusion dresses, fusion kurtis, fusion saree, fusion dress, designer fusion wear, ethnic fusion wear, fusion wear online, indo western fusion, fusion outfits',
        'Buy Latest Collection of Women Fusion Wear online in India. Choose From Kurtas, Designer Sarees, Dresses, Lehenga Choli & more of brands like Mitera, Anouk, Biba & more at Myntra Fashion store ✯ COD ✯ Discounts',
        1, '2021-02-21 13:32:52.616545', 'glenn', NULL, '', TRUE);
INSERT INTO public.category (id, parent_id, name, short_description, activate_on, deactivate_on, url_segment,
                             meta_keywords, meta_description, sort_order, created_on, created_by, modified_on,
                             modified_by, is_active)
VALUES ('3715c7fc-3c0e-4ee4-8fa0-dfd48e8e3a3a', '731b01bd-fab7-475e-adb2-6322eb9eac68', 'Sarees', 'Sarees',
        '2021-02-21', NULL, 'saree',
        'saree, sarees, women saree, new saree collection, fancy saree, online saree shopping, saree blouse designs,latest saree,new saree design,latest saree design, sari online',
        'Saree - Pick from the designer range of Saris online for ladies & girls. Buy formal, partywear, casual Sarees in various prints, patterns, types & more at Myntra store.',
        1, '2021-02-21 13:35:26.166935', 'glenn', NULL, '', TRUE);
INSERT INTO public.category (id, parent_id, name, short_description, activate_on, deactivate_on, url_segment,
                             meta_keywords, meta_description, sort_order, created_on, created_by, modified_on,
                             modified_by, is_active)
VALUES ('34c0d8ef-19a0-4f3a-8439-6d0510cfba04', '731b01bd-fab7-475e-adb2-6322eb9eac68', 'Kurtas & Suits',
        'Kurtas & Suits', '2021-02-21', NULL, 'women-kurtas-kurtis-suits',
        'kurtis online, designer kurti, ladies designers kurtis, designers kurtis, designer kurtis online, designers kurtis, suits online',
        'Women Kurtis & Kurtas Suits - Buy Designer Kurtas & Kurtis for Ladies online. Pick from Huge range kurtis, kurtas sets & suits for Women at Myntra ✯ COD ✯ Easy returns and exchanges',
        2, '2021-02-21 13:36:59.067196', 'glenn', NULL, '', TRUE);

我想从我的数据库中提取所有类别,以便像上面的类别层次结构那样在 UI 端轻松绑定。

谁能帮我查询一下?

【问题讨论】:

    标签: postgresql hierarchical-data postgresql-10


    【解决方案1】:

    --------- 修订版
    Parent、Sub、Leaf的确定比较简单:

    1. Row Child id 为 null 然后 Parent。
    2. 行子 id 不为空,行有子行,然后是子行。
    3. 否则叶子。

    唯一的困难是上面的2。
    现在可以通过几种方式清除它:

    • 使用相同的基本递归 CTE 应用超前和滞后功能 然后在主查询中检查空值。但是随着等级制度,这很快就会变得混乱。所以让我们拒绝这个想法。
    • 对 CTE 稍作修改后,非递归选择为 父母。在递归选择中查看当前是否有子行 然后是子类别。

    修改 CTE 并不算太糟糕,但选择它作为父母仍然有些讨厌。因此,下面将其抽象为一个简单的 SQL 函数,该函数返回适当的类型(假设 id 已知是一个孩子)。

    create or replace 
    function category_sub_or_leaf(id_in uuid)
      returns text
      language sql 
      strict 
    as $$ 
        select case when exists (select null
                                   from category
                                   where parent_id = id_in 
                                )   
                    then '(Sub Category)'
                    else '(leaf level category)'
                 end  ;
    $$;
    

    结果查询为:

    with recursive heir (id, parent_id, name, short_description, sort_order, root_path, lev, cat_level) as
        ( select  id, parent_id, name, short_description, sort_order,(name)::text, 1, '(Parent Category)'
            from category 
           where parent_id is null
          union all 
          select c.id, c.parent_id, c.name, c.short_description, c.sort_order, root_path || '>'||(c.name)::text, lev+1    
               , category_sub_or_leaf(c.id) 
            from category c
            join heir     h 
              on c.parent_id = h.id
        ) --select * from heir;                                                              
    select  (rpad(' ', 4*(lev-1),' ') || short_description) || ' ' || cat_level   description
      from heir
     order by root_path,lev,sort_order;
    

    参见revised demo: Demo 还冲出了女足用品,以在子类别中提供和额外的层。 I.E 2 层子类别。但由于我不想输入太多内容,因此我将表格修改为只需要必要的列。

    --------- 原版
    您正在寻找的是recursive cte。这里第一个(非递归项)选择获取没有定义 parent_id 的行。然后递归项(联合后)回顾前一行并检索子行。 (充其量是一个糟糕的描述。)查询构建返回第一个父级和当前深度的路径。然后使用这些生成的列来提供结果的顺序和缩进。见Demo

    with recursive heir as 
         ( select  id, parent_id, name, short_description, (name)::text path, 1 lev
             from category 
            where parent_id is null
           union all 
           select c.id, c.parent_id, c.name, c.short_description, path ||'>'||(c.name)::text, lev+1 
             from category c
             join heir     h 
               on c.parent_id = h.id
         ) 
    select (rpad(' ', 4*(lev-1),' ') || short_description) short_description
      from heir
     order by path, lev ;
    

    注意:使用 Postgres 13 构建的演示,因此函数 gen_random_uuid() 替换了 uuid_generate_v4()。

    【讨论】:

    • 谢谢你,但我在这里唯一想知道的是如何确定什么是父类别,什么是子类别或叶类别。我的意思是说我什么时候会使用你的查询在我的 UI 上绑定这些类别,使用一些 for 循环,然后应该有一个标志,说明这个“男士”是父类别或“上衣”是子类别,其他是“的叶子”上衣”。我不是在寻找任何 C# 代码,而是您的查询提供的数据,我无法在 UI 端区分父类别或子类别或叶类别。你能帮我识别一下吗?
    • 对不起,我错过了。当我向后滚动查看结果时,我想我只看了女性。如果您只想要“男性”的类别,应该很容易从“女性”中删除。请参阅修改后的答案。
    猜你喜欢
    • 2012-12-26
    • 1970-01-01
    • 2014-07-09
    • 2023-03-17
    • 2011-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-18
    相关资源
    最近更新 更多