如何从3表有条件地加入

时间:2019-02-09 01:32:13

标签: mysql sql join

我的数据库中有3个表,我的第一个表是个人表其存储所有人的名字,我的第二个表是爱好表其存储所有人的爱好,第三个表是参照表存储所有参考人和爱好。

Tabel person :               Tabel hobby :            Tabel referensi :

-----------------      ------------------    -------------------------------------
|  id  |  name  |      |  id  |  hobby  |    |  id  |  ref_person  |  ref_hobby  |
-----------------      ------------------    -------------------------------------
|   1  |  Rose  |      |   1  |  Makan  |    |   1  |    1         |    1        |
|   2  |  Lisa  |      |   2  |  Renang |    |   2  |    1         |    3        |
|   3  |  Jisoo |      |   3  |  Nyanyi |    |   3  |    1         |    4        |
|   4  |  Jennie|      |   4  |  Youtube|    |   4  |    3         |    5        |
-----------------      |   5  |  Masak  |    -------------------------------------
                       ------------------


I want to count all hobby by that person

Example I want select Rose :          Or I want select Jisoo :

---------------------------                    ---------------------------
|  id  |  hobby  |  count |                    |  id  |  hobby  |  count |
---------------------------                    ---------------------------
|  1   |  Makan  |  1     |                    |  1   |  Makan  |  0     |
|  2   |  Renang |  0     |                    |  2   |  Renang |  0     |
|  3   |  Nyanyi |  1     |                    |  3   |  Nyanyi |  0     |
|  4   |  Youtube|  1     |                    |  4   |  Youtube|  0     |
|  5   |  Masak  |  0     |                    |  5   |  Masak  |  1     |
---------------------------                    ---------------------------

等等,我该如何解决这个问题?

这是我编写的查询,但似乎不起作用,因为仅显示计数大于0的数据。

SELECT
    hobby.id,
    hobby.name,
    count( referensi.id ) AS count 
FROM
    referensi
    LEFT OUTER JOIN hobby ON hobby.id = referensi.ref_hobby
    JOIN person ON referensi.ref_person = person.id 
    WHERE person.id = 1
GROUP BY
    hobby.id

谢谢。

3 个答案:

答案 0 :(得分:1)

您可以尝试将条件恶化功能与OUTER JOIN一起使用

CASE WHEN中设置条件

查询1

SELECT
    hobby.id,
    hobby.name,
    COUNT(CASE WHEN person.id = 3 THEN 1 END) AS count 
FROM
    hobby  
    LEFT JOIN referensi  ON hobby.id = referensi.ref_hobby
    LEFT JOIN person ON referensi.ref_person = person.id 
GROUP BY
    hobby.id,
    hobby.name

Results

| id |    name | count |
|----|---------|-------|
|  1 |   Makan |     0 |
|  2 |  Renang |     0 |
|  3 |  Nyanyi |     0 |
|  4 | Youtube |     0 |
|  5 |   Masak |     1 |

答案 1 :(得分:1)

您要从hobby表开始加入,并使用LEFT JOIN选择调出其他表中的匹配记录。

SELECT
    h.id,
    h.hobby,
    count( p.id ) AS count 
FROM
    hobby h
    LEFT JOIN referensi r ON h.id = r.ref_hobby
    LEFT JOIN person p ON r.ref_person = p.id AND p.id = 1
WHERE p.name is NULL OR p.name = 'Rose'
GROUP BY h.id, h.hobby

使用表别名也是一种好习惯,我已将它们添加到您的查询中。

Demo on DB Fiddle 用户Rose:

| id  | hobby   | count |
| --- | ------- | ----- |
| 1   | Makan   | 1     |
| 2   | Renang  | 0     |
| 3   | Nyanyi  | 1     |
| 4   | Youtube | 1     |
| 5   | Masak   | 0     |

答案 2 :(得分:1)

要解决此问题,您需要JOIN referensiperson,仅在referensi中选择与感兴趣的人相对应的条目,然后RIGHT JOIN hobby。如果没有匹配的条目,则输出为0,否则为1。例如,对于人员1:

SELECT h.id, 
       h.hobby, 
       CASE WHEN r.id IS NULL THEN 0 ELSE 1 END AS count
FROM referensi r
JOIN person p ON p.id = r.ref_person AND p.id = 1
RIGHT JOIN hobby h ON h.id = r.ref_hobby
ORDER BY h.id

这也可以通过相关子查询来实现:

SELECT h.id, 
       h.hobby, 
       EXISTS (SELECT * FROM referensi r WHERE r.ref_hobby = h.id AND r.ref_person = 1) AS count
FROM hobby h

如果一个人/兴趣元组可以多次出现在referensi表中,则您需要执行COUNT

SELECT h.id, 
       h.hobby, 
       COUNT(r.id) AS count
FROM referensi r
JOIN person p ON p.id = r.ref_person AND p.id = 1
RIGHT JOIN hobby h ON h.id = r.ref_hobby
GROUP BY h.id

输出(针对示例数据的所有三个查询):

id  hobby       count
1   Makan       1
2   Renang      0
3   Nyanyi      1
4   Youtube     1
5   Masak       0

Demo on SQLFiddle