【问题标题】:How to join tables on multiple records and multiple fields如何在多个记录和多个字段上连接表
【发布时间】:2019-09-22 19:42:50
【问题描述】:

我需要一个相当复杂的 mySQL 连接的解决方案: 假设我们有 3 张桌子:T1、T2 和 T3。 表 1 包含主 ID 和名称字段。

表1

| ID | Name |
|  1 |   A  |
|  2 |   B  |
|  3 |   C  |
|  4 |   D  |

表 2 包含表 1 的 ID 和值的列

表2

| 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 但也有表3

表3

| 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 (..,..) 等等,但没有成功。

找到解决方案的人将获得永恒的名声!

【问题讨论】:

  • 您能告诉我们您使用的是什么版本的 MySQL 吗?

标签: mysql join multiple-records


【解决方案1】:
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 是保留字,因此作为表/列标识符的选择并不理想

【讨论】:

  • 这很好。缺少的一点是加入名称和值。 dbfiddle
【解决方案2】:

您做错了什么是将table3 加入到其他 2 个表中。
相反,您应该加入table3 的子查询,它返回满足您条件的oIDs:

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   |

【讨论】:

  • 是的!现在完全理解它,这很好用。它是永恒的名声!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-26
  • 2013-10-26
  • 2021-12-09
  • 1970-01-01
相关资源
最近更新 更多