从另一个表中选择查询

Posted

技术标签:

【中文标题】从另一个表中选择查询【英文标题】:Select query from another table 【发布时间】:2021-03-09 03:23:33 【问题描述】:

我有两张桌子:

CREATE TABLE store_category (
    store_id    int  NOT NULL PRIMARY KEY,
    category_id char NOT NULL
)

CREATE TABLE category (
    category_id char NOT NULL PRIMARY KEY,
    parent_id   char     NULL,
    name        char NOT NULL
)
store_id category_id
1 1a
2 2b
3 3c

category表:该表有3级类别。 parent_id中***别的类别有NULL

category_id parent_id name
1a NULL a
2b 1a b
3c 2b c

我想获取商店类别的所有相关类别名称。

预期的查询结果:

store_id category_id lv1 lv2 lv3
1 1a a b c
2 2b a b c
3 3c a b c

我有一个想法,我将与category 表中的每个category_id 相关的所有类别名称放入临时表中,然后将临时表与store_category 表连接起来。我想知道这是否是个好主意。

【问题讨论】:

1) 请不要大喊大叫(*所有大写字母都在喊叫)。 2)请不要使用图片,使用格式化文本。 3) SO 不是代码编写服务,请向我们展示您的尝试。 感谢您的评价,我马上修改 你最多只有 3 个关卡吗?从来没有 4?如果是这样,只需使用 3 个左连接。 是否只有一个层次结构(a/b/c)适用于所有商店?如果是这样,那么将category_id 分配给store_id 无关紧要,lv1 将始终为'a'lv2 'b'lv3 'c' 只有3个级别,但每个级别有多个值,可以是lv1aa。我的问题是获取与每个商店相关的所有类别。我正在尝试将左连接组合 3 次以找到 category_id 的***别。根据该组合表,我将得到所有subcategories。忘了说了,店铺不只是指同级别的品类 【参考方案1】:

我有一个想法,我会将与类别表中的每个 category_id 相关的所有类别名称放入临时表,然后将 join 临时表和 store_category 表。我想知道这是否是个好主意。

是个好主意——除非你不需要临时表——也不需要循环。您只需要一个递归(自引用)CTE。 CTE 是您选择数据层次结构和其他图形结构的方式。

但是,我认为将 PIVOT(或更具体地说,UNPIVOT)您的数据放入 lv1lv2lv3 列中并不是一个好主意 - 我知道您的业务规则说只有 3 级深度,但您的数据模型确实允许超过 3 级深度(除非您的 CHECK CONSTRAINTUDF 使用相同样式的 CTE 查询限制最大depth)。当您的数据维度随查询而变化时(例如这个!),那么您应该将它们作为行返回,然后格式化它们以便在您的应用程序代码中显示给最终用户,而不是直接在 SQL 中。

至于分层查询:请阅读:CTE Recursion to get tree hierarchy

类似这样的:

DECLARE @getThisCategoryId char(2) = '3c';

WITH my_cte AS (
    
    SELECT
        c.category_id,
        c.parent_id,
        c.name,
        1 AS depth
    FROM
        category AS c
    WHERE
        c.category_id = @getThisCategoryId 

    UNION ALL
    
    SELECT
        other_categories.category_id,
        other_categories.parent_id,
        other_categories.name,
        collected_so_far.depth + 1 AS depth
    FROM
        category AS other_categories
        INNER JOIN my_cte AS collected_so_far ON
            other_categories.category_id = collected_so_far.parent_id    
)
SELECT
    *
FROM
    my_cte
    INNER JOIN store_category AS sc ON my_cte = category_id
ORDER BY
    sc.store_id

【讨论】:

以上是关于从另一个表中选择查询的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 查询构建器 - 从另一个表中选择前 1 行

从另一个表中选择 * 以及计数/总和

从另一个表中选择一个表的否定以及oracle的主表sql查询中的数据

Mysql通过ID从另一个表中删除一个表

Mysql 从一个表中选择全部,从另一个表中选择一些使用别名

从表中选择数据并从另一个表中填充特定值