2017-04-11 54 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