一对多关联SELECT记录两个或两个以上条件

时间:2019-02-04 23:23:00

标签: mysql

我有两个表:

person

+-----+------------+---------------+
| id  | name       | address       |
+-----+------------+---------------+
| 1   | John Smith | 123 North St. |
| 2   | Joe Dirt   | 456 South St. |
+-----+------------+---------------+  

person_fields

+-----+------------+-----------+-------+
| id  | type       | person_id | value |
+-----+------------+-----------+-------+
| 1   | isHappy    | 1         | 1     |
| 2   | hasFriends | 1         | 1     |
| 3   | hasFriends | 2         | 1     |

我想从personisHappy为TRUE的hasFriends中选择所有人员。这是我尝试过的:

SELECT person.*
    FROM person
      INNER JOIN person_fields
        ON person.id = person_fields.person_id
    WHERE
      (person_fields.type = 'isHappy' AND person_fields.value IS TRUE)
      AND
      (person_fields.type = 'hasFriends' AND person_fields.value IS TRUE)

不幸的是,这不起作用,因为您无法在person_fields中拥有type = 'isHappy'type = 'hasFriends'的单个记录。我无法OR这两个条件,因为那样会同时返回约翰·史密斯和乔·迪尔特,但我只想要约翰·史密斯,因为他是唯一一个快乐并同时有朋友的人。

有什么建议吗?预先感谢!

4 个答案:

答案 0 :(得分:1)

参加两次:

SELECT person.*
FROM person
INNER JOIN person_fields happy
        ON person.id = happy.person_id AND happy.type='isHappy' AND happy.value
INNER JOIN person_fields friends
        ON person.id = friends.person_id AND friends.type='hasFriends' AND friends.value

答案 1 :(得分:1)

您可以两次加入person_fields,一次加入isHappy,一次加入hasFriends

SELECT p.*
FROM person p 
INNER JOIN person_fields f1 ON p.id = f1.person_id
INNER JOIN person_fields f2 ON f1.person_id = f2.person_id 
WHERE f1.type = 'isHappy' AND f2.type = 'hasFriends'

我不确定value字段的位置,但是您可以抛出一个额外的条件,或者在需要时输入两个条件

AND f1.value = 1 AND f2.value = 1

答案 2 :(得分:1)

标准解决方案如下:

SELECT person_id 
  FROM person_fields 
 WHERE type IN ('ishappy','hasfriends') 
 GROUP 
    BY person_id 
HAVING COUNT(1) = 2;

...其中'2'等于IN()中的参数个数

请注意,这假设(person_id,type)是唯一的

答案 3 :(得分:0)

如果您始终知道要检查的条件数,并且始终只想返回具有所有条件的person记录,则可以使用子查询并修改HAVING子句以选择typeperson_fields的最大数量:

SELECT
  p.id,
  p.name,
  (SELECT COUNT(DISTINCT pf.type) FROM person_fields AS pf WHERE pf.person_id = p.id and pf.value = true) AS types
FROM
  person AS p
HAVING types = 2

结果:

id  name       types
1   John Smith 2