首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MySQL计划冲突

MySQL计划冲突
EN

Stack Overflow用户
提问于 2008-12-28 08:22:32
回答 2查看 1.7K关注 0票数 1

嘿,我偶然发现了这个网站,正在寻找mySQL表中事件重叠的解决方案。我对这个解决方案印象深刻(已经很有帮助了),我想我应该看看我是否能得到更多的帮助……

好的,乔想和工作中的人换班。他有开庭日期。他打开换班表,调出本周的日程表(或者剩下的部分)。这是通过DB查询完成的。不客气。他选了一个班次。从这一点开始,事情就变得棘手了。

因此,首先,表单将shift start和shift end传递给脚本。它对班次与此班次重叠的任何人运行查询。他们不能同时工作两个班次,所以这个查询中的所有用户ID都被放在黑名单上。此查询如下所示:

代码语言:javascript
复制
SELECT DISTINCT user_id FROM shifts
WHERE
FROM_UNIXTIME('$swap_shift_start') < shiftend
AND FROM_UNIXTIME('$swap_shift_end') > shiftstart

接下来,我们对a)相同长度(公司策略),b)不与Joe正在工作的任何其他班次重叠的所有班次运行查询。

我目前拥有的是这样的东西:

代码语言:javascript
复制
SELECT *
FROM shifts
AND shiftstart BETWEEN  FROM_UNIXTIME('$startday') AND FROM_UNIXTIME('$endday')
AND user_id NOT IN ($busy_users) 
AND (TIME_TO_SEC(TIMEDIFF(shiftend,shiftstart)) = '$swap_shift_length')
$conflict_dates
ORDER BY shiftstart, lastname

现在,你可能想知道“什么是$conflict_dates?”

嗯,当Joe提交交换班次时,它会重新加载他当周的班次,以防他决定检查另一个班次的潜力。因此,当它执行第一个查询时,当脚本循环并输出他的选择时,它还构建了一个类似于以下内容的字符串:

代码语言:javascript
复制
AND NOT(
'joe_shift1_start' < shiftend
AND 'joe_shift1_end' > shiftstart)
AND NOT(
'joe_shift2_start' < shiftend
AND 'joe_shift2_end' > shiftstart)
...etc

因此,数据库将得到一个相当长的查询,查询内容如下:

代码语言:javascript
复制
SELECT *
FROM shifts
AND shiftstart BETWEEN  FROM_UNIXTIME('$startday') AND FROM_UNIXTIME('$endday')
AND user_id NOT IN ('blacklisteduser1', 'blacklisteduser2',...etc) 
AND (TIME_TO_SEC(TIMEDIFF(shiftend,shiftstart)) = '$swap_shift_length')
AND NOT(
'joe_shift1_start' < shiftend
AND 'joe_shift1_end' > shiftstart)
AND NOT(
'joe_shift2_start' < shiftend
AND 'joe_shift2_end' > shiftstart)
AND NOT(
'joe_shift3_start' < shiftend
AND 'joe_shift3_end' > shiftstart)
AND NOT(
'joe_shift4_start' < shiftend
AND 'joe_shift4_end' > shiftstart)
...etc
ORDER BY shiftstart, lastname

因此,我希望SQL有一些天才的方法,以更简单的方式处理这个问题,或者有人可以指出一个奇妙的逻辑原则,以更聪明的方式解释潜在的冲突。(请注意'start > end,end < start‘的用法,在我发现我使用的是betweens之前,我不得不从两端减去一分钟。)

谢谢!

一个

EN

Stack Overflow用户

发布于 2008-12-28 08:45:33

您可以将joe_shift{1,2,3}的值加载到临时表中,然后执行查询以对其进行连接,使用外部连接仅查找不匹配任何移位的移位:

代码语言:javascript
复制
CREATE TEMPORARY TABLE joes_shifts (
 shiftstart DATETIME
 shiftend   DATETIME
);
INSERT INTO joes_shifts (shiftstart, shiftend) VALUES
  ('$joe_shift1_start', '$joe_shift1_end'),
  ('$joe_shift2_start', '$joe_shift2_end'),
  ('$joe_shift3_start', '$joe_shift3_end'),
  ('$joe_shift4_start', '$joe_shift4_end');
-- make sure you have validated these variables to prevent SQL injection

SELECT s.*
FROM shifts s
  LEFT OUTER JOIN joes_shifts j
  ON (j.shiftstart < s.shiftend OR j.shiftend > s.shiftstart) 
WHERE j.shiftstart IS NULL
  AND s.shiftstart BETWEEN FROM_UNIXTIME('$startday') AND FROM_UNIXTIME('$endday')
  AND s.user_id NOT IN ('blacklisteduser1', 'blacklisteduser2',...etc) 
  AND (TIME_TO_SEC(TIMEDIFF(s.shiftend,s.shiftstart)) = '$swap_shift_length');

由于左外部联接,当joes_shifts中没有匹配的行时,列为NULL。

票数 1
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/395973

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档