从两个左连接中过滤数据
Filter data from two left joins
我有一些简化的数据:
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 列中有一些重复项。我需要的是将此查询过滤为 return 仅同时具有参数值 modem AND 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
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
ANDprinter
的任务,因此需要加入tablestbl_parameter
和 tbl_parameter_value
在查询中两次(使用 table 别名):
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%'
如果你想测试参数值是否完全等于modem
和printer
,你可以将WHERE
子句替换为:
WHERE tpv1.value = 'modem' AND tpv2.value = 'printer'
注意:如果您使用 LEFT JOIN
而不是 INNER JOIN
,查询将始终 return 来自 id
的所有值tbl_task
。这显然不是预期的结果。
阅读 documentation about the JOIN syntax 以了解更多信息。
我有一些简化的数据:
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 列中有一些重复项。我需要的是将此查询过滤为 return 仅同时具有参数值 modem AND 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
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
ANDprinter
的任务,因此需要加入tablestbl_parameter
和 tbl_parameter_value
在查询中两次(使用 table 别名):
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%'
如果你想测试参数值是否完全等于modem
和printer
,你可以将WHERE
子句替换为:
WHERE tpv1.value = 'modem' AND tpv2.value = 'printer'
注意:如果您使用 LEFT JOIN
而不是 INNER JOIN
,查询将始终 return 来自 id
的所有值tbl_task
。这显然不是预期的结果。
阅读 documentation about the JOIN syntax 以了解更多信息。