2016-11-12 7 views
1

私は2つのテーブルの予約とワーカーを持っています。基本的には、労働者のためのテーブルと、労働者が時間枠(別名:BOOKINGS)でしなければならないことを追跡するためのテーブルがあります。たとえば、JeffはWORKERSテーブルに属し、BOOKINGテーブルではJeffが2016-11-10から2016-11-15まで作業しています。SQL - 2つの異なるテーブルのデータを返す

私は仕事に利用可能な労働者がいるかどうかを確認しようとしています。私は2016-11-11から2016-11-14まで何かが必要だと言います。その時に予約されていない労働者がいるかどうかを確認し、その仕事に利用可能なすべての労働者を表示する必要があります。 私は予約を照会して、要求された時間に開始終了日の間に利用可能な労働者があるかどうかを確認します。

しかし、私がやっているのは、WORKERSテーブルとBOOKINGSテーブルの結合を行い、BOOKINGSから一致するデータと一致しないデータのみを返します。たとえば、私は10人の労働者を抱えており、4人の労働者はランダムな時間に本であるとします。私の質問は、BOOKINGSの4人の労働者のみをチェックし、まだ仕事をしていないすべての人を無視します。あなたが見ることができるように、それは大きな問題です。説明されているように利用可能なすべてのワーカーにどのように問い合わせますか?私は私のPHPスクリプトを介してロジックを行う必要がありますか?

ありがとうございます!!!!!!私はこれが複雑な作業であることを理解しています。

ワーカー表

CREATE TABLE WORKERS (
      ID INT NOT NULL AUTO_INCREMENT, 
      WORKER_NAME VARCHAR(80) NOT NULL, 
      WORKER_CODE INT, 
      WORKER_WAGE INT, 
      PRIMARY KEY (ID) 
) 

予約表

CREATE TABLE BOOKINGS (
      ID INT NOT NULL AUTO_INCREMENT, 
      WORKER_NAME VARCHAR(80) NOT NULL, 
      START DATE NOT NULL, 
      END DATE NOT NULL, 
      CLIENT_NAME VARCHAR(80) NOT NULL, 
      PRIMARY KEY (ID) 
) 

クライアント表(重要なものではないが)

​​

現在のクエリ

SELECT WORKERS.ID, WORKERS.WORKER_NAME, WORKERS.WORKER_CODE, WORKERS.WORKER_WAGE 
FROM WORKERS 
INNER JOIN BOOKINGS 
ON WORKERS.WORKER_NAME = BOOKINGS.WORKER_NAME 
WHERE (START NOT BETWEEN :start AND :end) 
ORDER BY WORKERS.ID 

PHP文

$conn = new PDO("mysql:host=$servername;dbname=$bname", $username, $password); 
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
$stmt = $conn->prepare("SELECT WORKERS.ID, WORKERS.WORKER_NAME, WORKERS.WORKER_CODE, WORKERS.WORKER_WAGE 
FROM WORKERS 
INNER JOIN BOOKINGS 
ON WORKERS.WORKER_NAME = BOOKINGS.WORKER_NAME 
WHERE (START NOT BETWEEN :start AND :end) 
ORDER BY WORKERS.ID 
"); 
$stmt->bindParam(':start', $start); 
$stmt->bindParam(':end', $end); 
$stmt->execute(); 
$result = $stmt->setFetchMode(PDO::FETCH_ASSOC); 
$workers = $stmt->fetchAll(); 

First

Second

Third

答えて

1

あなたはで利用可能なすべての労働者を選択することができます:それは `このケースでIN` NOTを使用しない方が良いです

SELECT * 
FROM WORKERS AS w 
WHERE NOT EXISTS ( 
    SELECT 1 
    FROM BOOKINGS 
    WHERE START BETWEEN :start AND :end 
     AND WORKER_NAME = w.WORKER_NAME 
) 
+0

「選択1」の目的は何ですか? – John

+0

何かを選択する必要があるので、選択するものはこの場合重要ではありません。重要なのは、サブクエリが少なくとも1つの行を戻すかどうかだけです。 – lovasoa

3

あなたは、与えられたタイムスロットで忙しい労働者のリストに含まれていないすべての労働者を選択することができます。

SELECT * 
FROM WORKERS 
WHERE WORKER_NAME NOT IN ( 
    SELECT WORKER_NAME 
    FROM BOOKINGS 
    WHERE START BETWEEN :start AND :end 
) 
+1

。 https://sqlperformance.com/2012/12/t-sql-queries/left-anti-semi-join – lovasoa

+0

NOT BETWEENを使用しないでください – John

+0

サブクエリはビジー状態の予約からすべてのワーカーを選択します。ビジー状態ではありません。 – Martin

関連する問題