6

利用可能かどうかに応じて、データベース テーブルからアイテムを表示するシステムを作成しています。

私は2つのテーブルを持っています:

予約:

----------------------------------------------------------------------
| 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 台あり、すべてがユーザーが入力した日付に予約されている場合、それらの carID はループから除外されます。ただし、Honda Civic はリストにまったく表示されません。

特定の日に特定のモデルの車がなくなったかどうかを確認する方法が必要です。私は 3 つの Civic を所有しており、3 つが除外されていることがわかっているため、1 つを表示していますが、予約することはできません。

解決策は、サブクエリを削除することだと思います。だから最初に私は実行します:

$nonavail = mysql_query("SELECT carID FROM reservations 
                         WHERE startDate = '".$sqlcoldate."'");
while($noavailrow = mysql_fetch_array($nonavail)) { 

これにより、除外する必要がある carID の配列が得られます。次に、すべての車を取得し、PHP と carID を使用してそれらを並べ替えることができます。しかし、私は今迷っています...

誰かが私を正しい方向に向けることができますか?

4

8 に答える 8

7

このようにそれを行うことが可能であるはずです:

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

内部サブクエリは、指定された時刻の前に開始時刻があり、後に終了時刻がある予約のみを選択します(で示されます?)。次に、外部クエリはすべての車を選択し、各車に属する予約を見つけようとします(1台の車でも、1台でもない場合もありますが、同じ車の予約を同時に複数持つことはできないため、複数あることはありません。時間)。最後に、結果セットがグループ化されmakemodelそれぞれの合計車数と予約数が計算され、その差が利用可能な車の数になります。

このアプローチは、ではないCOUNT()値のみをカウントするという事実を利用します。 NULL

于 2013-03-12T18:35:44.203 に答える
1

PHPソリューションを提供します。SQL はおそらくパフォーマンスの高いオプションであるため、これは実際にはスレッドにいくつかの多様性を追加するためのものです。

これが私が問題を理解する方法です。利用可能な車と、利用できないモデルごとに少なくとも 1 台の車を表示したいとします。すなわち:

  • フォード トーラス - 利用可能
  • フォード トーラス - 利用可能
  • ホンダ シビック - 利用不可
  • フンダイソナタ - 入手可能

...

// 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;
});
于 2013-03-13T03:50:41.763 に答える
0

私は解決すべき同様の問題を抱えています。

まず、予約済みの車を含むデータベースで予約されていない車を探していることを理解する必要があります...

データベースにない情報を探しています!
しかし、あなたはあなたが持っているものからそれを差し引くことができます。

比較の課題を簡素化するには、日付と時刻(予約テーブルと2つのユーザー基準(開始と終了))を「タイムスタンプ」形式に結合する必要があります...既存のすべての予約を次のように比較する方が簡単です。ユーザーリクエスト。フォーマット情報については、http
//db.apache.org/derby/docs/10.7/ref/rrefsqlj27620.htmlを参照してください。

したがって、ユーザーデータ(開始タイムスタンプと終了タイムスタンプ)を使用して予約済みの車を探し、すべての可能な車から除外する必要があります。

                  UserStart UserEnd
                         | |
ケースA|------ | | |
ケースB|-|-------- | |
ケースC| | ---------- | |
ケースD| | ------- | --- |
ケースE| | | ---------- |
ケースF|-------- | ------------------ | ---------------- |
                         | |


ケースAとEが必要です。

このスクリプトは、ケースB、C、D、およびFを検出する必要があります...そして、すべてのCarIDを「NotAvaibleCars」と呼ばれる配列に配置します。
ケースAとE(過去/終了予約と将来の予約)を忘れます。

次に、結果ページに表示する前に、車ごとにIDが「inArray」であるかどうかを確認する必要があります。

コード:

$allReservedCars = mysql_query("SELECT * from reservation") or die(mysql_error());

$allCars = mysql_query("SELECT * from cars") or die(mysql_error());

$NotAvailableCars = array();

$userStart = $_POST['yourClientStartCriteria'];
$userEnd = $_POST['yourClientEndCriteria'];

while ($allCarsCheck = mysql_fetch_array($allReservedCars)){
$TimestampStart = $allCarsCheck['startDate'] . ' ' . $allCarsCheck['startTime'];
$TimestampEnd = $allCarsCheck['startDate'] . ' ' .$allCarsCheck['startTime'];

if (
    (($TimestampStart>$userStart)&&($TimestampStart<$userEnd)) ||   // if cases C or D (A reservation start already exist for this car between userStart and userEnd)
    (($TimestampEnd>$userStart)&&($TimestampEnd<$userEnd)) ||       // if case B or C (A reservation end already exist for this car between userStart and userEnd)
    (($TimestampStart<$userStart)&&($TimestampEnd>$userEnd))        // if case F (A reservation that wraps userStart and userEnd already exist for this car)
   ) {

   array_push($NotAvailableCars, $allCarsCheck['CarID']); // You have now an array of the NOT available cars.

   }

}


while($searchcars = mysql_fetch_array($allcars)) {

 if (inArray($searchcars['CarID'],$NotAvailableCars)){
  //Do nothing!
 }
 else{
 // Your code to show this available car.
 }
}


;)


わかりました... 8時間後にもう一度ソリューションを読んでいます...
そして、主な質問を見逃したことがわかります。メーカーとモデルの組み合わせに使用できる車がないときに何かを表示することです。

私はそれに取り組みました...そして...ある種の解決策があります。
しかし、もっと良いものがあることを願っています...これが今のところ私が見ることができるすべてです。

$distinctMakeModel = mysql_query("SELECT distinct make, model from cars");
while ($row = mysql_fetch_array($distinctMakeModel)){
  array_push($CarModelArray, $row['make'] . ' -splitter- ' . $row['model']) // Array with all make/model combination

}

$CarQtyArray = array();
for($i=0;$i<$CarModelArray.length;$i++){
  $thisCar = explode(' -splitter- ',$carModelArray[$i]);

  $ThisCarQty = mysql_query("SELECT count(*) from cars where make=$thisCar[0] AND model=$thisCar[1]");
  $thiscar = mysql_fetch_array($ThisCarQty);
  array_push($CarQtyArray, $thiscar[0];     //So now you have an array of quantity with indexes matching the $carModelArray indexes.
}

これで、車のメーカー/モデルの配列と、インデックスが一致する数量の配列ができました。

コードの次のチャンクは、同じ一致するインデックスを持つ使用できない数量の配列を作成します。

for($i=0;$i<$CarModelArray.length;$i++){
  $thisCar = explode(' -splitter- ',$carModelArray[$i]);
  $NotAvailableCarQtyArray[$i] = 0;

  for($j=0;$j<$NotAvailableCars.length;$j++){
    $thisNotAvailable = mysql_query("Select count(*) where make=$thisCar[$i] AND model=$thisCar[$i] AND carID=$NotAvailableCars[$j]");
    $isThisTheModel = mysql_fetch_array($thisNotAvailable);
    if ($isThisTheModel<>'0'){
      $NotAvailableCarQtyArray[$i] ++;
    }

  }
}


だから今...
$CarModelArray [0]で、ホンダシビックを持っているとしましょう。
$ CarQtyArray [0]には3があり
、$ NotAvailableCarQtyArray [0]には3があります(すべてなくなっています!)。

for ($i=0;$i<$CarModelArray.length;$i++){
  if ($CarQtyArray[$i]==$NotAvailableCarQtyArray[$i]){
    echo $CarModelArray[$i] . ' are not available.<br>';
  }
}

これは、ここで多くのクエリにwaaayyyを取ります!!!
SQLクエリをループに入れるのは良い考えではありません。
しかし、もう一度...私は他の方法がわかりません。

これは、開始検索と終了検索の間に出ている車の数に、お持ちのメーカー/モデルの数を掛けたようなものです。

しかし、それはうまくいくはずです...
少なくとも私は試しました。
;)

于 2013-03-14T21:02:43.877 に答える
0

メーカーとモデルの「マスターリスト」を選択し、利用可能なものに左参加します。これは最も最適化された構文ではないかもしれませんが、かなり明確です。

select Models.*, Available.* from (select make, model from Cars 
GROUP BY make, model) as Models
LEFT JOIN (SELECT * FROM Cars WHERE CarID NOT IN (1,3,6)) as Available on Models.model = Available.model

予約済みの車を除外するロジックを削除し、テスト目的でNOTINに置き換えたことに気付くでしょう。ただし、プラグを差し込むのは簡単です。

http://sqlfiddle.com/#!2/266db/12/0を参照してください

于 2013-03-13T17:54:59.527 に答える
0

このクエリは、予約の開始日または終了日が、新しい顧客が車を希望する期間に発生するかどうかを確認します。利用可能な車を合計します。

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
于 2013-03-12T18:33:47.063 に答える
0

私が理解しているように、利用可能な車のリストと、「メーカー」と「モード」でグループ化された利用できない車のブランチのリストを取得したいと考えています (例: Honda Civid、Ford Escape)。したがって、2 つのクエリを作成するのは正しいと思いますが、2 番目のクエリは正しくないようです。

最初のクエリは、使用できない車を取得できない最初のクエリです。

2 番目のクエリは、'make' と 'model' でグループ化されたすべての車を取得できます。このクエリは次のようになります。$nonavail = mysql_query("SELECT carID FROM reservations WHERE startDate = '".$sqlcoldate."' GROUP BY 'make', 'type'");

2 つの配列を取得したら、レイアウト上で適切に操作して表示できます。1 つ目は利用可能な車、2 つ目は利用できない車の分岐であることに注意してください。

于 2013-03-17T18:59:35.563 に答える
0

ここでは、予約可能な車と利用できない車のリストを別々にするための解決策を示します。これは非常に便利です。

予約可能な車のリストを取得します。すなわち)。特定の日付間隔で予約可能..

select *,'available' as status from cars where CarID not in(SELECT CarID FROM reservations
WHERE UNIX_TIMESTAMP( CONCAT( startDate,  ' ', startTime ) ) <= $startTimestamp
AND UNIX_TIMESTAMP( CONCAT( endDate,  ' ', endTime ) ) >= $endTimestamp)WHERE deleted = 'no' group by make,model order by make,model asc

予約のために利用できない車のリストを取得します。すなわち)。特定の日付間隔ですでに予約されています..

select *,'not available' as status from cars where CarID not in(SELECT CarID FROM reservations
WHERE UNIX_TIMESTAMP( CONCAT( startDate,  ' ', startTime ) ) <= $startTimestamp
AND UNIX_TIMESTAMP( CONCAT( endDate,  ' ', endTime ) ) >= $endTimestamp)WHERE deleted = 'no' group by make,model order by make,model asc

注:日付をタイムスタンプ形式に変換してください..

$startDateTime="21/04/2013 13:00:00"; //date example
list($sDay, $sMonth, $sYear, $sHour, $sMinute,$sSeconds) = split('[/ :]', $startDateTime); 
$startTimestamp=mktime($sHour, $sMinute,$sSeconds, $sMonth, $sDay, $sYear);

$endDateTime="29/04/2013 13:00:00"; //date example
list($eDay, $eMonth, $eYear, $eHour, $eMinute,$eSeconds) = split('[/ :]', $endDateTime); 
$endTimestamp=mktime($eHour, $eMinute,$eSeconds, $eMonth, $eDay, $eYear);

コードは以下のとおりです。

<?php
$startDateTime="21/04/2013 13:00:00"; //date example
list($sDay, $sMonth, $sYear, $sHour, $sMinute,$sSeconds) = split('[/ :]', $startDateTime); 
$startTimestamp=mktime($sHour, $sMinute,$sSeconds, $sMonth, $sDay, $sYear);

$endDateTime="29/04/2013 13:00:00"; //date example
list($eDay, $eMonth, $eYear, $eHour, $eMinute,$eSeconds) = split('[/ :]', $endDateTime); 
$endTimestamp=mktime($eHour, $eMinute,$eSeconds, $eMonth, $eDay, $eYear);

$carstringAvailable = mysql_query("select *,'available' as status from cars 
                            WHERE CarID not in(
                                SELECT CarID FROM reservations
                                WHERE UNIX_TIMESTAMP( CONCAT( startDate,  ' ', startTime ) ) <= $start_Timestamp
                                  AND UNIX_TIMESTAMP( CONCAT( endDate,  ' ', endTime ) ) >= $end_Timestamp
                                  )
                            AND deleted = 'no' group by make,model order by make,model asc");

$getcarsAvailable = $carstringAvailable;
?>
<h3>Available cars for reservation</h3>
<table>
<tr>
    <th>CarID</th><th>make</th><th>model</th><th>serial</th><th>image</th><th>status</th>
</tr>
<?php 
if(mysql_num_rows($getcarsAvailable)>0)
{
    while($searchcarsAvail = mysql_fetch_array($getcarsAvailable)) 
    {
    ?>
    <tr>
        <td><?php echo $searchcarsAvail['CarID'];?></td>
        <td><?php echo $searchcarsAvail['make'];?></td>
        <td><?php echo $searchcarsAvail['model'];?></td>
        <td><?php echo $searchcarsAvail['serial'];?></td>
        <td><?php echo $searchcarsAvail['image'];?></td>
        <td><?php echo $searchcarsAvail['status'];?></td>
    </tr>
    <?php
    } 
}
else 
{
?>
    <tr>
        <td colspan='5'>No records found</td>
    </tr>
<?php 
}
?>
</table>

<?php 
$carstringUnAvailable = mysql_query("select *,'available' as status from cars 
                            WHERE CarID in(
                                SELECT CarID FROM reservations
                                WHERE UNIX_TIMESTAMP( CONCAT( startDate,  ' ', startTime ) ) <= $start_Timestamp
                                  AND UNIX_TIMESTAMP( CONCAT( endDate,  ' ', endTime ) ) >= $end_Timestamp
                                  )
                            AND deleted = 'no' group by make,model order by make,model asc");

$getcarsUnAvailable = $carstringUnAvailable;
?>
<h3>Already Reserved cars list</h3>
<table>
<tr>
    <th>CarID</th><th>make</th><th>model</th><th>serial</th><th>image</th><th>status</th>
</tr>
<?php
if(mysql_num_rows($getcarsUnAvailable)>0)
{ 
    while($searchcarsUnAvail = mysql_fetch_array($getcarsUnAvailable)) 
    {
    ?>
    <tr>
        <td><?php echo $searchcarsUnAvail['CarID'];?></td>
        <td><?php echo $searchcarsUnAvail['make'];?></td>
        <td><?php echo $searchcarsUnAvail['model'];?></td>
        <td><?php echo $searchcarsUnAvail['serial'];?></td>
        <td><?php echo $searchcarsUnAvail['image'];?></td>
        <td><?php echo $searchcarsUnAvail['status'];?></td>
    </tr>
    <?php 
    }
 }
 else 
{
?>
    <tr>
        <td colspan='5'>No records found</td>
    </tr>
<?php 
}
?>
</table>
于 2013-03-19T13:08:13.927 に答える
0
$carstring = mysql_query("SELECT *,(SELECT count(CarID) FROM reservations WHERE reservations.CarID=cars.CarID AND '".$sqlcoldate."' NOT BETWEEN startDate AND endDate ) as availability FROM cars {$statement} AND deleted = 'no' GROUP BY model");

上記のクエリは、利用可能な特定のモデルの車の数を運ぶ追加のフィールド (availability) を持つ車のリストを提供します。車が利用できない場合、フィールドにはゼロが表示されます。

于 2013-03-15T11:40:18.607 に答える