如何在同一张表上进行多个连接,然后与另一个表连接?
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 = gender
和 prod_attr=Male
和 maingroup = Pants。这意味着,我想要所有性别为男性且属于 Pants 的产品。我什至想打印 prodgroup 并加入需要prod_name
的product_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
【讨论】:
以上是关于如何在同一张表上进行多个连接,然后与另一个表连接?的主要内容,如果未能解决你的问题,请参考以下文章