mysql - 过滤来自两个左连接的数据

标签 mysql left-join where-clause

我有一些简化的数据:

mysql> SELECT * FROM tbl_task;
+----+----------+
| id | data     |
+----+----------+
|  1 | data 1   |
|  2 | data 2   |
|  3 | data 3   |
|  4 | data 4   |
|  5 | data 55  |
|  6 | data 166 |
+----+----------+

mysql> SELECT * FROM tbl_parameter;
+----+---------+----------+
| id | task_id | name     |
+----+---------+----------+
|  1 |       1 | hardware |
|  2 |       1 | hardware |
|  3 |       1 | hardware |
|  4 |       2 | hardware |
|  5 |       2 | hardware |
|  6 |       3 | hardware |
|  7 |       3 | hardware |
|  8 |       3 | hardware |
|  9 |       4 | hardware |
| 10 |       5 | hardware |
| 11 |       5 | hardware |
| 12 |       5 | hardware |
| 13 |       6 | hardware |
| 14 |       6 | hardware |
+----+---------+----------+

mysql> SELECT * FROM tbl_parameter_value;
+----+--------------+---------+
| id | parameter_id | value   |
+----+--------------+---------+
|  1 |            1 | modem   |
|  2 |            2 | printer |
|  3 |            3 | 220     |
|  4 |            4 | 24      |
|  5 |            5 | modem   |
|  6 |            6 | printer |
|  7 |            7 | 220     |
|  8 |            8 | gps     |
|  9 |            9 | 24      |
| 10 |           10 | printer |
| 11 |           11 | modem   |
| 12 |           12 | 220     |
| 13 |           13 | 24      |
| 14 |           14 | modem   |
+----+--------------+---------+

所以,任务有多个参数,每个参数都有一个值。这可能看起来没有意义,但这只是简化的数据。

我使用两个连接来获取value数据:

mysql> SELECT tbl_task.id, tbl_parameter_value.value
    -> FROM tbl_task
    -> LEFT JOIN tbl_parameter ON tbl_task.id = tbl_parameter.task_id
    -> LEFT JOIN tbl_parameter_value ON tbl_parameter.id = tbl_parameter_value.parameter_id;
+----+---------+
| id | value   |
+----+---------+
|  1 | modem   |
|  1 | printer |
|  1 | 220     |
|  2 | 24      |
|  2 | modem   |
|  3 | printer |
|  3 | 220     |
|  3 | gps     |
|  4 | 24      |
|  5 | printer |
|  5 | modem   |
|  5 | 220     |
|  6 | 24      |
|  6 | modem   |
+----+---------+

如您所见,task.id 列中有一些重复项。我需要的是过滤此查询以仅返回同时具有参数值调制解调器和打印机的任务。

以下查询显然没有任何意义:

SELECT tbl_task.id, tbl_parameter_value.value
FROM tbl_task
LEFT JOIN tbl_parameter ON tbl_task.id = tbl_parameter.task_id
LEFT JOIN tbl_parameter_value ON tbl_parameter.id = tbl_parameter_value.parameter_id
WHERE value LIKE '%modem%' AND value LIKE '%printer%'

我也尝试过:

SELECT tbl_task.id, tbl_parameter_value.value
FROM tbl_task
LEFT JOIN tbl_parameter ON tbl_task.id = tbl_parameter.task_id
LEFT JOIN tbl_parameter_value ON tbl_parameter.id = tbl_parameter_value.parameter_id AND tbl_parameter_value.value LIKE '%modem%' OR tbl_parameter_value.value LIKE '%printer%'

它给出了错误的结果以太。

如何同时过滤具有参数值调制解调器和打印机的不同任务?
根据这些数据我需要得到的是:

+----+
| id |
+----+
|  1 |
|  5 |
+----+

最佳答案

由于您需要查找具有参数值 modem AND printer 的任务,因此有必要连接表 tbl_parametertbl_parameter_value 在查询中两次(使用表别名):

SELECT t.id
FROM tbl_task t
INNER JOIN tbl_parameter tp1 ON t.id = tp1.task_id
INNER JOIN tbl_parameter tp2 ON t.id = tp2.task_id
INNER JOIN tbl_parameter_value tpv1 ON tp1.id = tpv1.parameter_id
INNER JOIN tbl_parameter_value tpv2 ON tp2.id = tpv2.parameter_id
WHERE tpv1.value LIKE '%modem%' AND tpv2.value LIKE '%printer%'

如果您想测试参数值是否与 modemprinter 完全相同,您可以将 WHERE 子句替换为:

WHERE tpv1.value = 'modem' AND tpv2.value = 'printer'

注意:如果您使用 LEFT JOIN 而不是 INNER JOIN,查询将始终返回所有 id来自tbl_task的值。这显然不是预期的结果。

阅读documentation about the JOIN syntax了解更多信息。

关于mysql - 过滤来自两个左连接的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43340992/

相关文章:

php - 如何将 MySQL 查询的结果转换为 PHP 中的整数?

PHP MYSQL PDO 列的 SUM

mysql - 如何从 MySQL 中选择表名称为变量的位置

mysql - jquery datepicker 日历 - 用 mysql vb 填充

Mysql选择哪里

mysql - 当您连接 2 个具有相同模式的表并检查除一个字段外的所有字段是否相等时,如何避免在 SQL 中编写冗长的 where 子句?

mysql - 如何优化评级表的 JOIN 和 AVG 语句

mysql - Laravel 4.2 Eloquent 关系 leftjoin ON 复杂

mysql - 如何连接不同表中的多行和单行

php - MySQL Select...Where 子句返回语法错误