所以我有2张桌子照顾和客户,就像这样
client {
id,
name
}
caring {
id,
startDate,
endDate,
clientId
}
Run Code Online (Sandbox Code Playgroud)
我需要让所有在两个提供的日期之间至少有一天可用的客户,您可以看到我的屏幕截图作为参考.
截图我有两个客户端,我需要返回它们.如您所见,第一个客户在提供期间(16.5.-29.5.)之间有三个免费日(21.5.-23.5.),而第二个客户没有任何关怀期.
到目前为止,我尝试过这样的事情
SELECT * FROM client cl
WHERE cl.id NOT IN (SELECT clientId FROM caring
WHERE endDate >= CURDATE() AND endDate <= DATE_ADD(CURDATE(), INTERVAL 14 DAY))
Run Code Online (Sandbox Code Playgroud)
这个只返回没有照顾的客户.这部分是我需要的,因为此查询不包括我的屏幕截图中的第一个客户端.然后我尝试了下面的查询.
SELECT ca.startDate, ca.endDate, cl.firstName, cl.lastName
FROM caring ca
LEFT JOIN client cl on cl.id = ca.clientId
WHERE ca.startDate NOT IN (
SELECT endDate
FROM caring
) AND ca.startDate <= '2017-05-29' AND ca.endDate >= '2017-05-16'
Run Code Online (Sandbox Code Playgroud)
但我没有得到理想的结果.
任何想法我怎么能实现这一点,提前thx!
选择感兴趣的时间段内的护理,并将开始/结束日期分别限制在该时间段内。此限制将允许更轻松地计算“已预订”(即以后的非空闲天数)。
SELECT ca.id,
-- Limit start/end dates to period of interest, respectively
GREATEST (ca.startDate, '2017-05-16') AS `effectiveStartDate`,
LEAST (ca.endDate, '2017-05-29') AS `effectiveEndDate`,
ca.clientId
FROM carings ca
WHERE ca.startDate <= '2017-05-29' AND ca.endDate >= '2017-05-16';
Run Code Online (Sandbox Code Playgroud)
接下来,计算预订天数:
DATEDIFF (DATE_ADD (LEAST (ca.endDate, '2017-05-29'), INTERVAL 1 DAY),
GREATEST (ca.startDate, '2017-05-16'))
AS `effectiveDays`
Run Code Online (Sandbox Code Playgroud)
最后,过滤掉整个期间预订的客户。这是通过比较来完成的
GROUP BY) 至HAVING sumDays < DATEDIFF(...))。由于您还希望在整个期间都没有预订的客户,我建议从表开始clients并“仅” LEFT JOIN(有效)carings:
SELECT cl.id, cl.name, IFNULL (SUM (eca.effectiveDays), 0) AS `sumDays`
FROM clients cl
LEFT JOIN
(SELECT ca.id,
-- Limit start/end dates to period of interest, respectively
GREATEST (ca.startDate, '2017-05-16') AS `effectiveStartDate`,
LEAST (ca.endDate, '2017-05-29') AS `effectiveEndDate`,
DATEDIFF (
DATE_ADD (LEAST (ca.endDate, '2017-05-29'), INTERVAL 1 DAY),
GREATEST (ca.startDate, '2017-05-16'))
AS `effectiveDays`,
ca.clientId
FROM carings ca
WHERE ca.startDate <= '2017-05-29' AND ca.endDate >= '2017-05-16')
eca -- effectiveCarings
ON eca.clientId = cl.id
GROUP BY cl.id, cl.name
HAVING sumDays <
DATEDIFF (DATE_ADD ('2017-05-29', INTERVAL 1 DAY), '2017-05-16')
ORDER BY cl.id;
Run Code Online (Sandbox Code Playgroud)
另请参阅http://sqlfiddle.com/#!9/1038b9/19