我正在开发一个系统来管理租赁流程,我想知道如果目前租用该对象,如何有效地查询所有可租用对象的人名,当前正在租用它。否则该列中应该为NULL。
我的表格如下:
对象
| object_id | object_name |
---------------------------
| 1 | Object A |
| 2 | Object B |
| 3 | Object C |
| 4 | Object D |
| 5 | Object E |
---------------------------
人
| person_id | person_name |
---------------------------
| 1 | John Doe |
| 2 | Jane Doe |
| 3 | Max Muster |
| 4 | Foobar |
---------------------------
租赁
| rental_id | rental_state| person_person_id |
----------------------------------------------
| 1 | open | 1 |
| 2 | returned | 1 |
| 3 | returned | 2 |
| 4 | open | 3 |
| 5 | returned | 4 |
----------------------------------------------
rental2object
| rental_rental_id | object_object_id |
---------------------------------------
| 1 | 1 |
| 2 | 2 |
| 2 | 3 |
| 3 | 3 |
| 4 | 2 |
| 4 | 5 |
| 5 | 2 |
---------------------------------------
我想要的结果应该是这样的:
| object_id | object_name | rented_to |
-------------------------------------------
| 1 | Object A | John Doe |
| 2 | Object B | Max Muster |
| 3 | Object C | NULL |
| 4 | Object D | NULL |
| 5 | Object E | Max Muster |
-------------------------------------------
到目前为止我得到的是:
SELECT `object_id`, `object_name`, `person_name` FROM `object`
LEFT JOIN `rental2object` ON `object_id` = `object_object_id`
LEFT JOIN `rental` ON `rental_id` = `rental_rental_id` AND `rental_state` = 'open'
LEFT JOIN `person` ON `person_id` = `person_person_id`
GROUP BY `object_id`
显而易见的问题是我不知道在分组时如何聚合正确的方法。
实现目标的最有效方法是什么?感谢您的帮助。
修改
更正了预期结果,以便将对象B租借给Max Muster。
答案 0 :(得分:1)
对象#2和#5都在#4租赁中。但是,根据您的预期结果,您将以不同的方式处理两者。对象E和对象B都应该是相同的行为,因为它们在同一个租赁中。如果没有,你应该解释女巫是了解产品是否有相关人员的标准。
要符合 SQL92 ,您应该在select子句中包含所有非聚合列:
SELECT `object_id`, `object_name`, `person_name` as rented_to
FROM `object`
...
GROUP BY `object_id`, `object_name`, `person_name`
要符合 SQL99 ,你应该在select子句中包含所有非函数依赖的非聚合列,在你的情况下,它们是object_id和object_name之间的依赖:object_id -> object_name
(字段< em> rental_state 将依赖功能分解为 person ),然后你就可以写了:
SELECT `object_id`, `object_name`, `person_name` as rented_to
FROM `object`
...
GROUP BY `object_id`, `person_name`
MySQL 5.7.5及更高版本实现了对功能依赖的检测,然后这最后一个选择是有效的,但我建议你,为了便于阅读,请使用第一个。
阅读MySQL Handling of GROUP BY了解更多信息和ONLY_FULL_GROUP_BY
参数详情。
请确保您拥有以下索引:
答案 1 :(得分:-1)
试试这个
SELECT
o.object_id,
o.object_name,
p.person_name AS rent_to
FROM
rental2object ro
RIGHT JOIN object o ON ro.object_object_id = o.object_id
LEFT JOIN rental r ON ro.rental_rental_id = r.rental_id AND r.rental_status = 'open'
JOIN person p ON r.person_person_id = p.person_id
答案 2 :(得分:-1)
SELECT `object_id`, `object_name`,
case
when rental_state = 'Open' then `person_name`
when r1.rental_rental_id is null then null
else `rental_state`
end as RentedTo
FROM `object`
LEFT JOIN `rental2object` r1 ON `object_id` = r1.`object_object_id`
LEFT JOIN `rental` ON `rental_id` = r1.`rental_rental_id`
LEFT JOIN `person` ON `person_id` = `person_person_id`
where r1.rental_rental_id =
(select max(r2.`rental_rental_id`)
from `rental2object` r2
where r2.`object_object_id` = r1.`object_object_id`
group by r2.`object_object_id`)
or r1.rental_rental_id is null
GROUP BY `object_id`;