如何在同一张表上进行多个连接,然后与另一个表连接?

Posted

技术标签:

【中文标题】如何在同一张表上进行多个连接,然后与另一个表连接?【英文标题】:How to do multiple join on same table and then join with another table? 【发布时间】:2016-01-13 11:37:43 【问题描述】:

我想在同一张表上进行内部连接,即 product_attributes 我想要 prod_value = genderprod_attr=Male 和 maingroup = Pants。这意味着,我想要所有性别为男性且属于 Pants 的产品。我什至想打印 prodgroup 并加入需要prod_nameproduct_master 表。我怎样才能做到这一点?

表 1:Product_attributes

+----+------------+-----------+------------+
| id | prod_style | prod_attr | prod_value |
+----+------------+-----------+------------+
|  1 | 0010       | gender    |       Male |
|  2 | 0010       | maingroup |      Pants |
|  3 | 0010       | prodgroup |  Pants_Abc |
|  4 | 0010       | Blue      |      color |
|  5 | 0011       | gender    |       Male |
|  6 | 0011       | maingroup |      Pants |
|  7 | 0011       | prodgroup |  Pants_Pqr |
|  8 | 0012       | gender    |     Female |
|  9 | 0012       | maingroup |      Pants |
| 10 | 0012       | prodgroup |      Pants |
| 11 | 0013       | gender    |     Female |
| 12 | 0013       | maingroup |    Jackets |
+----+------------+-----------+------------+

表 2:Product_master

+----+------------+-----------+
| id | prod_style | prod_name | 
+----+------------+-----------+
|  1 | 0010       | ABC       |
|  2 | 0011       | PQR       |
|  3 | 0012       | XYZ       |
|  4 | 0013       | LMN       |
+----+------------+-----------+

我已经尝试过这个解决方案:

select 
    * 
from 
    product_master pm 
    INNER JOIN (select 
                    * 
                from 
                    product_attributes 
                where 
                    prod_value='prodgroup' 
                        and prod_style in(select 
                                                prod_style 
                                          from 
                                                product_attributes 
                                           where 
                                                prod_attr ='pants' 
                                                and prod_value='mainGroup' 
                                                and prod_style in(select 
                                                                        prod_style 
                                                                   from 
                                                                        product_attributes 
                                                                   where 
                                                                        prod_attr='Male'
                                                                  )
                                           )
                ) p ON pm.prod_style = p.prod_style  
ORDER By 
    prod_name

使用我的解决方案,我得到了输出,但不知道其编写查询的方式是否正确。

使用上述解决方案输出:

+-----------+------------+-----------+-------------+-----------+-----------+
| id        | prod_style | prod_name | prod_style  | prod_attr | prod_value|
+-----------+------------+-----------+-------------+-----------+-----------+
|  1        | 0010       | ABC       |0010         |Pants_Abc  |prodgroup  |
|  2        | 0011       | PQR       |0011         |Pants_Pqr  |prodgroup  |
|  3        | 0012       | XYZ       |0012         |Pants      |prodgroup  |
|  4        | 0013       | LMN       |0013         |skinny     |prodgroup  |
+-----------+------------+-----------+-------------------------------------+

【问题讨论】:

@piya 你能解释一下你想要什么吗?我在做这个工作! (我想要所有性别为男性且属于裤子的产品) 我上面已经解释过了。我想获取所有性别为男性且主组为裤子的产品 【参考方案1】:

试试这个..

SELECT  *
FROM    product_master pm
        JOIN ( SELECT   t1.*
               FROM     product_attributes t1
                        JOIN product_attributes t2 ON t1.prod_style = t2.prod_style
                                                      AND t2.prod_attr = 'gender'
                                                      AND t2.prod_value = 'male'
                        JOIN product_attributes t3 ON t1.prod_style = t3.prod_style
                                                      AND t3.prod_attr = 'maingroup'
                                                      AND t3.prod_value = 'Pants'
             ) pa ON pm.prod_style = pa.prod_style

【讨论】:

【参考方案2】:

我已经建立了这个查询:

DECLARE @Product_attributes TABLE
(
    id INT
    , prod_style VARCHAR(10)
    , prod_attr VARCHAR(10)
    , prod_value VARCHAR(10)
);

DECLARE @Product_master TABLE
(
    ID INT
    , prod_style VARCHAR(10)
    , prod_name VARCHAR(10)
);

INSERT INTO @Product_attributes (id, prod_style, prod_attr, prod_value)
VALUES (1, '0010', 'gender','Male')
    , (2, '0010', 'maingroup','Pants')
    , (3, '0010', 'prodgroup', 'Pants_Abc')
    , (4, '0010', 'Blue', 'color')
    , (5, '0011', 'gender', 'Male')
    , (6, '0011', 'maingroup', 'Pants')
    , (7, '0011', 'prodgroup', 'Pants_Pqr')
    , (8, '0012', 'gender', 'Female')
    , (9, '0012', 'maingroup', 'Pants')
    , (10, '0012', 'prodgroup', 'Pants')
    , (11, '0013', 'gender', 'Female')
    , (12, '0013', 'maingroup', 'Jackets');

INSERT INTO @Product_master (id, prod_style, prod_name)
VALUES (1, '0010', 'ABC')
    , (2, '0011', 'PQR')
    , (3, '0012', 'XYZ')
    , (4, '0013', 'LMN');

SELECT PA1.id, PA1.prod_style, PM.prod_name, PA1.prod_attr, PA1.prod_value
FROM @Product_attributes AS PA1
INNER JOIN @Product_master AS PM
    ON PM.prod_style = PA1.prod_style
WHERE PA1.prod_attr = 'mainGroup'
    AND PA1.prod_value = 'Pants'
    AND EXISTS (
        SELECT 1
        FROM @Product_attributes AS PA2
        WHERE PA2.prod_style = PA1.prod_style
            AND PA2.prod_attr = 'gender'
            AND PA2.prod_value = 'Male'
        );

它会检查您的产品(基于prod_style)是否适合男性和裤子。必须满足两个条件,但它的输出与您的不同,即:

╔════╦════════════╦═══════════╦═══════════╦════════════╗
║ id ║ prod_style ║ prod_name ║ prod_attr ║ prod_value ║
╠════╬════════════╬═══════════╬═══════════╬════════════╣
║  2 ║       0010 ║ ABC       ║ maingroup ║ Pants      ║
║  6 ║       0011 ║ PQR       ║ maingroup ║ Pants      ║
╚════╩════════════╩═══════════╩═══════════╩════════════╝

我在你的逻辑中丢失了什么吗?请告诉我。

【讨论】:

它在具有 10-11 条记录的演示表上提供输出,但原始表具有超过 1,00,000 条记录,您的查询不起作用。它显示正在加载.. 查询未执行。 它会抛出错误信息吗?如果没有,请查看索引。 您的查询已执行,但耗时较长。 它会带来正确的结果吗?如果是这样,您需要查看索引或可能的性能改进。【参考方案3】:

试试这个,它将每个 other attr 放在自己的行上:

select pm.prod_style, pm.prod_name, pa.prod_attr, pa.prod_value
from Product_attributes pa
join Product_attributes pa_m on pa.prod_style = pa_m.prod_style
    and pa_m.prod_attr = 'gender' and pa_m.prod_value = 'Male'
join Product_attributes pa_g on pa.prod_style = pa_m.prod_style
    and pa_g.prod_attr = 'maingroup' and pa_g.prod_value = 'Pants'
join Product_master pm on pm.prod_style = pa.prod_style
where pa.prod_attr not in ('gender', 'maingroup')

如果您希望每个产品有一行,请尝试以下操作:

select pm.prod_style, pm.prod_name, group_concat(concat(pa.prod_attr, '=', pa.prod_value)) attrs
from Product_attributes pa
join Product_attributes pa_m on pa.prod_style = pa_m.prod_style
    and pa_m.prod_attr = 'gender' and pa_m.prod_value = 'Male'
join Product_attributes pa_g on pa.prod_style = pa_m.prod_style
    and pa_g.prod_attr = 'maingroup' and pa_g.prod_value = 'Pants'
join Product_master pm on pm.prod_style = pa.prod_style
where pa.prod_attr not in ('gender', 'maingroup')
group by 1, 2

这将产生类似的输出

prod_style | prod_name | attrs
0010       | ABC       | color=Blue,size=Large

【讨论】:

以上是关于如何在同一张表上进行多个连接,然后与另一个表连接?的主要内容,如果未能解决你的问题,请参考以下文章

oracle数据库:表连接

MySQL - 使用 COUNT 在同一个表上进行完全外连接

Mysql在同一张表上的多个左连接

Excel:VLOOKUP 将一列与另一张表匹配并连接数据

同一张表上的多个连接:转换状态

同一张表上的多个连接,在一个查询中计数