2017-04-11 55 views
0

我有一些简单的数据:筛选数据连接

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柱有些重复。我需要的是过滤此查询,以便同时返回参数值为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 | 
+----+ 

回答

1

既然你需要找到一个任务与参数值modemprinter,有必要加入表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,查询将始终从tbl_task返回所有id值。这显然不是预期的结果。

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

+0

哇!我以前从未见过两次加入。我无法理解它甚至是如何工作的。但它很好用,谢谢!顺便说一下,如果我只需要任务数据,那么使用何种类型的JOIN无关紧要? – Exerion

+0

阅读我的(编辑)答案的底部。 – Jocelyn