我有一对多的关系表。
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
答案 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
请按照以下链接查看正在运行的演示:
答案 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的两个部分丢弃。