SQL - 从两个不同的表返回数据

时间:2016-11-12 18:11:35

标签: php mysql sql sql-server

我有两张表BOOKINGS和WORKERS。基本上有一个工作人员的表,以及一个表,用于跟踪工人在时间范围内所做的事情(BOOKINGS)。例如,Jeff属于WORKERS表,而在BOOKING表格中,Jeff的工作时间为2016-11-10至2016-11-15。

我正在尝试检查是否有可用的工作人员。说我需要在2016-11-11至2016-11-14之间完成一些工作。我需要能够查看当时是否有未预订的工人,并显示可用于该工作的所有工人。 因此,我查询预订以检查在开始结束日期之间是否有可用工作人员。

但是,我这样做的方式是连接表WORKERS和BOOKINGS,它只返回BOOKINGS中的匹配和非匹配数据。例如,假设我有10名工人,4名工人在随机时间预订。我的查询只检查BOOKINGS中的4个工人,并忽略所有尚未完成工作的WOEKERS。你可以看到这是一个很大的问题。我如何查询所描述的所有可用工人?我必须通过我的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)
)

客户表(虽然不重要)

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

2 个答案:

答案 0 :(得分:3)

您可以选择在给定时间段内不在工作人员列表中的所有工作人员。

select     a.project_id, a.title, a.phone, b.office_phone 
from       tbl as a
left join  tbl as b 
        on a.project_id = b.project_id
       and b.office_phone is not null
where      a.phone is not null
union
select     a.project_id, a.title, b.phone, a.office_phone 
from       tbl as a
left join  tbl as b
        on a.project_id = b.project_id
       and b.phone is not null
where      a.office_phone is not null
and        b.phone is null
order by 1, 2, 3, 4;

答案 1 :(得分: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
)