MySQL JOIN查询仅包含几个特定值之一

时间:2016-10-04 05:04:03

标签: mysql

我有一对多的关系表。

rental
------
id
book_date

prices
------
rental_id
type_id
value

正常的JOIN查询会给出结果

select * from rental a join prices b on a.id = b.rental_id;
id book_date  rental_id  type_id  value

1, 2016-10-04,  1,        8,       200
1, 2016-10-04,  1,       10,       300
2, 2016-10-04,  2,        8,       250
3, 2016-10-04,  3,        8,       200
3, 2016-10-04,  3,       10,       300

我想要的是,如果价格记录的type_id = 10,则取该行;如果没有,则采用type_id = 8的行。我想要的结果:

1    2016-10-04    1    10    300
2    2016-10-04    2     8    250
3    2016-10-04    3    10    300

我有这个查询,但似乎不能解决我的问题:

select * from rental a
join prices b 
on a.id = b.rental_id and 
      ( if(b.type_id = 10, b.type_id = 10, b.type_id = 8) )
ORDER BY a.id DESC LIMIT 20

2 个答案:

答案 0 :(得分:1)

  

如果价格记录的type_id = 10那么它只与type_id 10一起加入,如果它没有加入type_id = 8

可以通过为每个type_id选择最大rental_id的记录来强制执行此逻辑。如果是这样,那么您可以简单地添加第三个连接条件,该条件将结果集限制为仅匹配此额外条件的记录:

SELECT a.*, b.*
FROM rental a
INNER JOIN prices b
    ON a.id = b.rental_id
INNER JOIN
(
    SELECT rental_id,
           CASE WHEN MAX(CASE WHEN type_id = 10 THEN 1 END) = 1 THEN 10
                WHEN MAX(CASE WHEN type_id = 8 THEN 1 END)  = 1 THEN 8
                ELSE MAX(type_id)
           END AS type_id
    FROM prices
    GROUP BY rental_id
) c
    ON b.rental_id = c.rental_id AND
       b.type_id   = c.type_id

请按照以下链接查看正在运行的演示:

SQLFiddle

答案 1 :(得分:1)

  

我想要的是,如果价格记录的type_id = 10那么它只是加入   使用type_id 10,如果不是,则使用type_id = 8

连接

这意味着如果有的话,带有type_id 8的记录将被丢弃 带有type_id 10的另一个记录。“另一个”调用另一个JOIN,实际上是LEFT JOIN,因为要比较的记录可能不存在:

SELECT a.*, b.* FROM rental a
JOIN prices b ON (a.id = b.rental_id)
LEFT JOIN prices check ON (a.id = check.rental_id AND check.type_id = 10)

WHERE b.type_id = 10 OR (b.type_id = 8 AND check.type_id IS NULL)

这意味着JOIN将获得所有类型8和类型10的;然后LEFT JOIN将使它只有在没有相应的类型10时才采用类型8:

       1 10 10
       2 8  10      # discarded
       2 10 10
       3 8  NULL
       4 15 NULL    # discarded
       4 8  NULL

ID 1只有10条记录,两个查询都检索它,并且它被接受。 ID 2具有两者,因此8-10记录被丢弃,因为b类型是8,但c类型不是NULL。 ID 3只有8条记录,因此寻求10的LEFT JOIN返回NULL,这符合OR的第二部分。 ID 4具有type_ids 8和15,并且15的一个被OR的两个部分丢弃。