我正在创建一个系统来显示数据库表中的项目,具体取决于它们是否可用。
我有两个表:
预订:
----------------------------------------------------------------------
| ResID | CarID | UserID | startTime | startDate | endTime | endDate |
----------------------------------------------------------------------
| 1 | 4 | 4 | 13:00:00 |2013-04-21 |13:00:00 |2013-04-29|
和汽车:
-------------------------------------------
| CarID | make | model | serial | image |
-------------------------------------------
| 1 | Honda | civic | ky675 | 1.png |
因此,当用户访问页面时,他们输入开始日期和结束日期,然后在运行查询以检查汽车在该日期是否可用后显示汽车列表。
所以我想到了这个查询。
$carstring = mysql_query("SELECT * FROM cars
{$statement}
AND deleted = 'no'
AND carID NOT IN (
SELECT carID FROM reservations
WHERE startDate = '".$sqlcoldate."'
)
GROUP BY model");
它所做的是从数据库中选择所有汽车,然后排除作为子查询数组结果的 carID 数组。其余的汽车,它按模型分组并循环显示它们,如下所示:
$getcars = $carstring;
while($searchcars = mysql_fetch_array($getcars)) {
**some HTML showing car imag and make etc etc**
}
这个“有效”。例如,如果我有 5 辆本田 Civics,并且它们都在用户输入的日期被预订,它们的 carID 将被排除在循环之外。然而,它根本不会在列表中显示本田思域,因为它们都将消失。
我需要一种方法来判断我是否在特定日期用完了特定型号的汽车。所以我有三辆思域,我知道有三辆被排除在外,所以我展示了一辆,但它无法预订。
我认为解决方案是删除子查询。所以首先我运行:
$nonavail = mysql_query("SELECT carID FROM reservations
WHERE startDate = '".$sqlcoldate."'");
while($noavailrow = mysql_fetch_array($nonavail)) {
这为我提供了一组我需要排除的 carID,然后我可以获取所有汽车并使用 PHP 和我的 carID 对它们进行排序。但我现在迷路了......
有人可以指出我正确的方向吗?
最佳答案
应该可以这样做:
SELECT c.make, c.model, count(c.carid) - count(x.resid) available_cars
FROM cars c
LEFT JOIN (
SELECT r.carid, r.resid
FROM reservations r
WHERE ? BETWEEN r.startdate AND r.enddate) x ON x.carid = c.carid
WHERE c.deleted = 'no'
GROUP BY c.make, c.model
ORDER BY c.make, c.model
内部子查询将只选择那些开始时间在给定时间之前和结束时间在给定时间之后的预订(由 ?
表示)。外部查询然后选择所有汽车并尝试找到属于每辆车的预订(可以有一个也可以没有,但不能超过一个,因为我猜你不能同时对同一辆车进行多个预订时间)。最后,结果集按 make
和 model
分组,并计算每组的汽车总数和预订数量,差值就是可用汽车的数量。
这种方法利用了 COUNT()
只计算不 NULL
的值这一事实。
关于PHP:一种通过循环排序并在查询后排除某些条目的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15325509/