[英]Mysql case join query assistance
I'm trying to create a query which gets all columns and a case column which denotes availablity, however I need to include a one to many relationship in the mix and it's messing with my head.我正在尝试创建一个查询,它获取所有列和一个表示可用性的 case 列,但是我需要在混合中包含一对多的关系,这让我很困惑。
My query without the relationship:我的查询没有关系:
SELECT storage_rooms.*,
CASE
WHEN release_date <= CURDATE() THEN 1
WHEN release_date <= ADDDATE(CURDATE(), INTERVAL 30 DAY) THEN release_date
ELSE 0
END AS available
FROM storage_rooms
Which is fine and returns something like this:这很好,并返回如下内容:
Now I need to check if it is already booked.现在我需要检查它是否已经被预订了。 To give you an idea of what I'm thinking (doesn't work):
为了让您了解我在想什么(不起作用):
SELECT storage_rooms.*,
(SELECT
CASE
WHEN release_date <= CURDATE() OR orders.status_id IN (3, 4) THEN 1
WHEN release_date <= ADDDATE(CURDATE(), INTERVAL 30 DAY) THEN release_date
ELSE 0
END AS available
FROM storage_rooms
LEFT OUTER JOIN orders
ON storage_rooms.id = orders.storage_room_id)
FROM storage_rooms
I gather I might need another subquery with a groupBy?我想我可能需要另一个带有 groupBy 的子查询? I don't find joins super intuitive and I'm a bit lost so any assistance would be welcome.
我不觉得连接超级直观,我有点迷茫,所以欢迎任何帮助。
I'm not totally sure it will work but you can try this:我不完全确定它会起作用,但你可以试试这个:
SELECT storage_rooms.*,
CASE
WHEN release_date <= CURDATE() OR availibility.order_status_id IN (3, 4) THEN 1
WHEN release_date <= ADDDATE(CURDATE(), INTERVAL 30 DAY) THEN release_date
ELSE 0
END AS available
FROM storage_rooms
LEFT JOIN
( SELECT id AS order_id, status_id AS order_status_id, storage_room_id AS order_storage_room_id
FROM orders WHERE status_id IN (3, 4)
GROUP BY storage_room_id
) availibility
ON (storage_rooms.id = availibility.order_storage_room_id)
The thing here is that the LEFT JOIN
is adding to the results the columns needed to check your availability.这里的问题是
LEFT JOIN
将检查可用性所需的列添加到结果中。 But the trick is you need a subquery so that the table joined contains only one entry for each room or else the results are duplicated.但诀窍是您需要一个子查询,以便连接的表只包含每个房间的一个条目,否则结果会重复。 The subquery must be limited to the positive matches you want to take in consideration with a
WHERE
, because the GROUP BY
will only keep the first row found and you don't want this information lost in the grouping.子查询必须仅限于您要考虑使用
WHERE
的正匹配,因为GROUP BY
只会保留找到的第一行,并且您不希望此信息在分组中丢失。
FROM OP'S COMMENTS THE FINAL QUERY IS:根据 OP 的评论,最终的问题是:
SELECT storage_rooms.*,
CASE
WHEN release_date <= CURDATE() OR aggregate.order_status_id IS NULL THEN 1
WHEN release_date <= ADDDATE(CURDATE(), INTERVAL 30 DAY) THEN release_date
ELSE 0
END AS available
FROM storage_rooms
LEFT JOIN
(SELECT storage_room_id, order_status_id
FROM orders WHERE order_status_id IN (1, 2)
GROUP BY storage_room_id, order_status_id
) aggregate
ON storage_rooms.id = aggregate.storage_room_id
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.