【问题标题】: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 你能解释一下你想要什么吗?我在做这个工作! (我想要所有性别为男性且属于裤子的产品)
  • 我上面已经解释过了。我想获取所有性别为男性且主组为裤子的产品

标签: mysql sql-server join


【解决方案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
    

    【讨论】:

      猜你喜欢
      • 2015-05-18
      • 2015-07-24
      • 1970-01-01
      • 1970-01-01
      • 2015-08-16
      • 1970-01-01
      • 2020-03-13
      • 2016-03-07
      相关资源
      最近更新 更多