2016-11-12 1 views
1

두 개의 테이블 예약 및 작업자가 있습니다. 기본적으로 근로자를위한 테이블과 근로자가 일주일에해야하는 일 (부킹)을 추적하는 테이블이 있습니다. 예를 들어 Jeff는 WORKERS 테이블에 속해 있고 BOOKING 테이블에서는 Jeff가 2016-11-10에서 2016-11-15까지 작업하고 있습니다.SQL - 두 개의 다른 테이블에서 데이터를 반환

작업에 사용할 수있는 직원이 있는지 확인하려고합니다. 2016-11-11에서 2016-11-14까지 필요한 조치가 필요하다고 가정 해보십시오. 그 당시에 예약되지 않은 근로자가 있는지 알아볼 수 있어야하고, 그 일에 사용할 수있는 모든 근로자를 표시 할 수 있어야합니다. 그래서 요청한 시간에 시작일 사이에 사용 가능한 작업자가 있는지 확인하기 위해 예약을 쿼리합니다.

그러나 내가하고있는 방식은 WORKERS 및 BOOKINGS 테이블 조인을 수행하고 BOOKINGS에서 일치하는 데이터와 일치하지 않는 데이터 만 반환합니다. 예를 들어 나는 10 명의 근로자를두고 4 명의 근로자는 무작위로 책을 가지고 있다고 말한다. 내 질문은 BOOKINGS에있는 4 명의 근로자 만 검사하고 아직 직업이없는 모든 우승자는 무시합니다. 당신도 알다시피 큰 문제입니다. 설명 된대로 모든 사용 가능한 작업자를 어떻게 쿼리합니까? 내 PHP 스크립트를 통해 논리를해야합니까?

감사합니다 !!!!!! 나는 이것이 복잡한 작업이며 당신이 이것을 읽은 시간을 appereite라고 이해합니다.

근무 표

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) 
) 

클라이언트 표 (중요하지 비록)

CREATE TABLE CLIENTS (
      ID INT NOT NULL AUTO_INCREMENT, 
      CLIENT_NAME VARCHAR(80) NOT NULL, 
      ADDRESS VARCHAR(100) 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

당신은 함께 사용할 수있는 모든 근로자를 선택할 수 있습니다

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

당신은 무언가를 선택해야하기 때문에, 당신이 선택한 것은이 경우 중요하지 않습니다. 중요한 것은 하위 쿼리가 적어도 하나의 행을 반환하는지 여부입니다. – lovasoa

3

당신은 주어진 시간 슬롯에 바쁜 노동자의 목록에없는 모든 근로자를 선택할 수 .

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

그것은이 경우 IN' NOT'사용하지 않는 것이 좋습니다. https://sqlperformance.com/2012/12/t-sql-queries/left-anti-semi-join – lovasoa

+0

NOT BETWEEN을 사용하지 마십시오 – John

+0

하위 쿼리는 사용중인 예약에서 모든 작업자를 선택합니다. 바쁜 것은 선택되지 않았습니다. – Martin

관련 문제