首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP:一种对循环进行排序并在查询后排除某些条目的方法

问PHP:一种对循环进行排序并在查询后排除某些条目的方法
EN

Stack Overflow用户
提问于 2013-03-11 01:54:26
回答 8查看 806关注 0票数 6

我正在创建一个系统,它显示数据库表中的项,这取决于它们是否可用。

我有两张表:

预订:

代码语言:javascript
复制
----------------------------------------------------------------------
| ResID | CarID | UserID | startTime | startDate | endTime | endDate  |
----------------------------------------------------------------------
|   1   |   4   |    4   | 13:00:00  |2013-04-21 |13:00:00 |2013-04-29|

和汽车:

代码语言:javascript
复制
-------------------------------------------
| CarID  |  make | model | serial | image |
-------------------------------------------
|   1    | Honda | civic | ky675  | 1.png | 

因此,当用户访问页面时,他们输入开始日期和结束日期,然后在运行查询以检查汽车在该日期是否可用后,显示汽车列表。

所以我想出了这个问题。

代码语言:javascript
复制
$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数组。其余的汽车,它按模型分组,并在循环中显示它们,如下所示:

代码语言:javascript
复制
$getcars = $carstring;
while($searchcars = mysql_fetch_array($getcars)) {

 **some HTML showing car imag and make etc etc**

 }

这是“有效”的。例如,如果我有5辆本田Civics,并且它们都是在用户输入的日期预订的,那么它们的carID将被排除在循环之外。然而,它根本不会在列表中显示本田思域,因为它们都会消失。

我需要一种方法来判断我是否在某个日期用完了某个型号的汽车。所以我有三个Civics,我知道有三个被排除了,所以我显示了一个,但它不能预订。

我认为解决方案是删除子查询。因此,首先我运行:

代码语言:javascript
复制
$nonavail = mysql_query("SELECT carID FROM reservations 
                         WHERE startDate = '".$sqlcoldate."'");
while($noavailrow = mysql_fetch_array($nonavail)) { 

这给了我一个需要排除的carID数组,然后我可以抓取所有的汽车,并使用PHP和我的carID对它们进行排序。但我现在迷路了..。

谁能给我指一下正确的方向?

EN

回答 8

Stack Overflow用户

发布于 2013-03-13 02:35:44

应该可以这样做:

代码语言:javascript
复制
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类型的值。

票数 7
EN

Stack Overflow用户

发布于 2013-03-13 11:50:42

我将提供一个PHP解决方案。SQL可能是性能更好的选项,所以这实际上只是给线程增加了一些变化。

下面是我对这个问题的理解。您希望显示可用的汽车,并为每个不可用的车型至少显示一辆汽车。即:

  • 福特金牛座-提供
  • 福特金牛座- Available
  • Honda思域- Unavailable
  • Hundai -可提供

..。

代码语言:javascript
复制
// Keep track of the models so we know which ones we have already processed
$models = array();

// Filter the array of results
array_filter( $results, function ( $result ) use ( &$models )
{
    // If the model has not yet been represented, add the model to the models 
    // array and return true, preserving this item in the array
    if ( !in_array( $result->model, $models )
    {
        $models[] = $result->model;
        return true;
    }

    // If the car is in the excluded list, remove this item from the array
    if ( in_array( $result->car_id, $excluded_car_ids ) )
    {
        return false;
    }

    return true;
});
票数 1
EN

Stack Overflow用户

发布于 2013-03-13 02:33:47

此查询检查预订的开始日期或结束日期是否发生在新客户希望购买汽车的期间。它对可用的汽车进行求和。

代码语言:javascript
复制
SELECT c.model, ... ,
  SUM(
    CASE WHEN (r.startDate BETWEEN $desiredstart AND $desiredend) OR
              (r.endData BETWEEN $desiredstart AND $desiredend)  
         THEN 0
         ELSE 1 END) as num_available
FROM cars c 
  LEFT JOIN reservations r 
  ON (c.CarID=r.CarID)
WHERE
  r.deleted = 'no' (
    SELECT carID FROM reservations 
       WHERE 
         AND
 ) 
GROUP BY c.model
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15325509

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档