如何连接多个记录和多个字段的表
How to join tables on multiple records and multiple fields
我需要一个相当复杂的 mySQL 连接的解决方案:
假设我们有 3 个表:T1、T2 和 T3。
Table1 包含主要 ID 和名称字段。
Table1
| ID | Name |
| 1 | A |
| 2 | B |
| 3 | C |
| 4 | D |
Table 2 包含一个用于 Table 1 的 ID 的列和一个值
Table2
| ID | oID | Value |
| 1 | 1 | aaa |
| 2 | 1 | bbb |
| 3 | 1 | ccc |
| 4 | 2 | ddd |
| 5 | 2 | eee |
| 6 | 3 | fff |
| 7 | 3 | ggg |
| 8 | 3 | hhh |
| 9 | 4 | iii |
到目前为止一切顺利,一个简单的 JOIN 将使我获得链接到 Table1.Name 的 Table2.Values
但是还有Table 3
Table3
| ID | oID | Condition | Value |
| 1 | 1 | color | red |
| 2 | 1 | brightness | 20 |
| 3 | 2 | color | green |
| 4 | 2 | brightness | 50 |
| 5 | 2 | saturation | 100 |
| 6 | 3 | color | green |
| 7 | 3 | brightness | 40 |
| 8 | 3 | saturation | 70 |
| 9 | 4 | color | purple|
我需要做的是获取 T1.Name,以及所有相关的 T2.Values 仅当 T3 的 2 个(或更多)条件都正常时:
例如:
匹配 T2.Values 的所有名称 IF T3.Condition = 'green' AND T3.brightness = 50
因为只有 ID 2 是绿色,亮度为 50,所以应该给我
B ddd
B eee
我尝试了几种方法:
SELECT t1.ID,
t1.Name,
t2.Value
FROM
Table1 t1
JOIN Table2 t2 ON t1.ID = t2.oID
JOIN Table3 t3 ON t1.ID = t3.oID
WHERE
t3.Condition = 'color'
AND
t3.Value = 'green'
AND
t3.Condition = 'brightness'
AND
t3.Value = 50
GROUP BY p.ID
当然没有结果,因为没有记录满足所有四个条件
SELECT t1.ID,
t1.Name,
t2.Value
FROM
Table1 t1
JOIN Table2 t2 ON t1.ID = t2.oID
JOIN Table3 t3 ON t1.ID = t3.oID
WHERE
(t3.Condition = 'color' AND t3.Value = 'green')
AND
(t3.Condition = 'brightness'AND t3.Value = 50)
GROUP BY p.ID
同样的结果:没有
SELECT t1.ID,
t1.Name,
t2.Value
FROM
Table1 t1
JOIN Table2 t2 ON t1.ID = t2.oID
JOIN Table3 t3 ON t1.ID = t3.oID
WHERE
(t3.Condition = 'color' AND t3.Value = 'green')
OR
(t3.Condition = 'brightness' AND t3.Value = 50)
GROUP BY p.ID
我得到了所有亮度为 50 和绿色的记录...但没有同时具有这两种情况的记录。
我也尝试了 JOIN ON 语句中的条件、LEFT JOINS、WHERE 条件 IN (..,..) 等等,但没有成功。
找到解决方案的人将名垂青史!
SELECT * FROM table3;
+----+-----+------------+--------+
| ID | oID | condition | value |
+----+-----+------------+--------+
| 1 | 1 | color | red |
| 2 | 1 | brightness | 20 |
| 3 | 2 | color | green |
| 4 | 2 | brightness | 50 |
| 5 | 2 | saturation | 100 |
| 6 | 3 | color | green |
| 7 | 3 | brightness | 40 |
| 8 | 3 | saturation | 70 |
| 9 | 4 | color | purple |
+----+-----+------------+--------+
9 rows in set (0.00 sec)
mysql>
SELECT x.oid
FROM table3 x
WHERE (x.condition,x.value) IN(('color','green'),('brightness','50'))
GROUP
BY x.oid
HAVING COUNT(*) = 2;
+-----+
| oid |
+-----+
| 2 |
+-----+
请注意 condition
是一个保留字,因此作为 table/column 标识符
并不是一个理想的选择
您做错的是您将 table3
连接到其他 2 个表。
相反,您应该加入 table3
的子查询,其中 returns 满足您条件的 oID
:
SELECT t1.name, t2.value
FROM table1 t1
INNER JOIN table2 t2 ON t1.id = t2.oid
INNER JOIN (
SELECT oID FROM table3
GROUP BY oID
HAVING SUM(`condition` = 'color' AND value = 'green') > 0
AND SUM(`condition` = 'brightness' AND value = '50') > 0
) t3 ON t1.id = t3.oID
参见demo。
结果:
| name | value |
| ---- | ----- |
| B | ddd |
| B | eee |
我需要一个相当复杂的 mySQL 连接的解决方案: 假设我们有 3 个表:T1、T2 和 T3。 Table1 包含主要 ID 和名称字段。
Table1
| ID | Name |
| 1 | A |
| 2 | B |
| 3 | C |
| 4 | D |
Table 2 包含一个用于 Table 1 的 ID 的列和一个值
Table2
| ID | oID | Value |
| 1 | 1 | aaa |
| 2 | 1 | bbb |
| 3 | 1 | ccc |
| 4 | 2 | ddd |
| 5 | 2 | eee |
| 6 | 3 | fff |
| 7 | 3 | ggg |
| 8 | 3 | hhh |
| 9 | 4 | iii |
到目前为止一切顺利,一个简单的 JOIN 将使我获得链接到 Table1.Name 的 Table2.Values 但是还有Table 3
Table3
| ID | oID | Condition | Value |
| 1 | 1 | color | red |
| 2 | 1 | brightness | 20 |
| 3 | 2 | color | green |
| 4 | 2 | brightness | 50 |
| 5 | 2 | saturation | 100 |
| 6 | 3 | color | green |
| 7 | 3 | brightness | 40 |
| 8 | 3 | saturation | 70 |
| 9 | 4 | color | purple|
我需要做的是获取 T1.Name,以及所有相关的 T2.Values 仅当 T3 的 2 个(或更多)条件都正常时: 例如: 匹配 T2.Values 的所有名称 IF T3.Condition = 'green' AND T3.brightness = 50 因为只有 ID 2 是绿色,亮度为 50,所以应该给我
B ddd
B eee
我尝试了几种方法:
SELECT t1.ID,
t1.Name,
t2.Value
FROM
Table1 t1
JOIN Table2 t2 ON t1.ID = t2.oID
JOIN Table3 t3 ON t1.ID = t3.oID
WHERE
t3.Condition = 'color'
AND
t3.Value = 'green'
AND
t3.Condition = 'brightness'
AND
t3.Value = 50
GROUP BY p.ID
当然没有结果,因为没有记录满足所有四个条件
SELECT t1.ID,
t1.Name,
t2.Value
FROM
Table1 t1
JOIN Table2 t2 ON t1.ID = t2.oID
JOIN Table3 t3 ON t1.ID = t3.oID
WHERE
(t3.Condition = 'color' AND t3.Value = 'green')
AND
(t3.Condition = 'brightness'AND t3.Value = 50)
GROUP BY p.ID
同样的结果:没有
SELECT t1.ID,
t1.Name,
t2.Value
FROM
Table1 t1
JOIN Table2 t2 ON t1.ID = t2.oID
JOIN Table3 t3 ON t1.ID = t3.oID
WHERE
(t3.Condition = 'color' AND t3.Value = 'green')
OR
(t3.Condition = 'brightness' AND t3.Value = 50)
GROUP BY p.ID
我得到了所有亮度为 50 和绿色的记录...但没有同时具有这两种情况的记录。
我也尝试了 JOIN ON 语句中的条件、LEFT JOINS、WHERE 条件 IN (..,..) 等等,但没有成功。
找到解决方案的人将名垂青史!
SELECT * FROM table3;
+----+-----+------------+--------+
| ID | oID | condition | value |
+----+-----+------------+--------+
| 1 | 1 | color | red |
| 2 | 1 | brightness | 20 |
| 3 | 2 | color | green |
| 4 | 2 | brightness | 50 |
| 5 | 2 | saturation | 100 |
| 6 | 3 | color | green |
| 7 | 3 | brightness | 40 |
| 8 | 3 | saturation | 70 |
| 9 | 4 | color | purple |
+----+-----+------------+--------+
9 rows in set (0.00 sec)
mysql>
SELECT x.oid
FROM table3 x
WHERE (x.condition,x.value) IN(('color','green'),('brightness','50'))
GROUP
BY x.oid
HAVING COUNT(*) = 2;
+-----+
| oid |
+-----+
| 2 |
+-----+
请注意 condition
是一个保留字,因此作为 table/column 标识符
您做错的是您将 table3
连接到其他 2 个表。
相反,您应该加入 table3
的子查询,其中 returns 满足您条件的 oID
:
SELECT t1.name, t2.value
FROM table1 t1
INNER JOIN table2 t2 ON t1.id = t2.oid
INNER JOIN (
SELECT oID FROM table3
GROUP BY oID
HAVING SUM(`condition` = 'color' AND value = 'green') > 0
AND SUM(`condition` = 'brightness' AND value = '50') > 0
) t3 ON t1.id = t3.oID
参见demo。
结果:
| name | value |
| ---- | ----- |
| B | ddd |
| B | eee |