我正在开发一个汽车租赁网站。我有两个表test_tbl_cars
和test_reservations
。
我正在使用搜索查询(在"How do I approach this PHP/MYSQL query?"中由Jon Kloske填写):
$sql = mysql_query("SELECT
test_tbl_cars.*,
SUM(rental_start_date <= '$ddate' AND rental_end_date >= '$adate') AS ExistingReservations
FROM test_tbl_cars
LEFT JOIN test_reservations USING (car_id)
GROUP BY car_id
HAVING ExistingReservations = 0");
这为我提供了出色的搜索结果,但test_tbl_cars
表包含许多汽车,在任何给定的搜索中都会返回几个相同的汽车模型。
如何过滤查询返回,以便我获得每个模型中的一个?
答案 0 :(得分:0)
使用Distict子句
$sql = mysql_query("SELECT
DISTINCT test_tbl_cars.model, test_tbl_cars.*,
SUM(rental_start_date <= '$ddate' AND rental_end_date >= '$adate') AS ExistingReservations
FROM test_tbl_cars LEFT JOIN test_reservations USING(car_id) GROUP BY car_id HAVING ExistingReservations = 0“);
答案 1 :(得分:0)
所以你遇到的问题是,在另一个问题中,每个房间都有一个唯一的ID,这是人们有兴趣预订的独特房间。在这里,您将可预订项目的概念扩展到特定类别的项目池(在本例中为汽车模型)。
可能有一种方法可以在没有子查询的情况下执行此操作,但到目前为止,最简单的方法是简单地从我的其他答案中获取原始想法并通过将其包装在另一个查询中来扩展它分组到模型中(正如您很快就会看到的那样,我们可以免费获得一些其他有用的东西)。
所以,首先让我们先获取具有冲突预订计数的汽车列表(根据我对其他答案的更新):
(我将这些示例作为起点使用您的查询,但请注意您确实应该使用预准备语句,或者至少使用数据库驱动程序提供的转义函数来处理这两个参数&#39 ;再过去)
SELECT car_id, model_id, SUM(IF(rental_id IS NULL, 0, rental_start_date <= '$ddate' AND rental_end_date >= '$adate')) AS ConflictingReservations
FROM test_tbl_cars
LEFT JOIN test_reservations USING (car_id)
GROUP BY car_id
这将为每个car_id返回一行,为您提供型号,以及与您指定的日期范围(0或更多)冲突的预订数量。
现在,在这个阶段,如果我们询问个别汽车(而不仅仅是可用汽车的型号),我们可以限制和订购结果&#34; HADING ConflictingReservations = 0 ORDER BY model_id&#34;什么的。
但是,如果我们想获得〜模型〜的可用性列表,我们需要对这些结果进行进一步分组以获得最终答案:
SELECT model_id, COUNT(*) AS TotalCars, SUM(ConflictingReservations = 0) AS FreeCars, CAST(IFNULL(GROUP_CONCAT(IF(ConflictingReservations = 0, car_id, NULL) ORDER BY car_id ASC), '') AS CHAR) AS FreeCarsList
FROM (
SELECT car_id, model_id, SUM(IF(rental_id IS NULL, 0, rental_start_date <= '$ddate' AND rental_end_date >= '$adate')) AS ConflictingReservations
FROM test_tbl_cars
LEFT JOIN test_reservations USING (car_id)
GROUP BY car_id
) AS CarReservations
GROUP BY model_id
您会注意到我们所做的就是通过model_id对原始查询进行分组,然后使用聚合函数为我们提供model_id,这是我们拥有此模型的总车数,免费计数我们通过计算汽车零冲突预测的所有时间来实现这种模型的汽车,最后是一个可爱的一点SQL,它返回逗号分隔的免费汽车car_ids列表(如果还需要!)
关于性能的快速说法:所有左连接,分组和子查询都可能使此查询确实非常慢。好消息是,外部团队应该只需要处理尽可能多的行,因此在您最终拥有大量汽车之前,它不应该很慢。然而,内部查询连接两个表(可以使用索引快速完成),然后按整个组进行分组,在每一行上执行函数。这可能会变得非常缓慢,特别是随着预订和汽车数量的增加。为了缓解这种情况,您可以在内部查询上使用where子句,并将其与适当的索引相结合,以减少要检查的项目数。您还可以使用其他技巧将开始日期和结束日期的比较移动到连接条件中,但这是另一天的主题:)
最后,与往常一样,如果有不正确的边缘情况,错误,错误的语法,等等 - 让我知道,我会编辑纠正!