【问题标题】:MYSQL extremely difficult Select QueryMYSQL极难选择查询
【发布时间】:2015-02-12 20:44:07
【问题描述】:

所以我有一个围绕驾驶学校构建的场景,在这所驾驶学校内有工作人员,他们扮演不同的角色。我正在尝试找到一种方法来检查未来几天或一周内特定员工的日程安排。在谷歌搜索 BETWEEN 和 JOIN 的不同变体一个小时后,我找不到一个可以让我获得“时间表”的版本。

这是我第一次尝试用我的 AND 和 OR 做得过火:

SELECT staff.staff_id, lname, interviewstart, lessondate, lessontime, prac_date, prac_time
FROM staff, interviews, lessons, practicaltests
WHERE staff.staff_id = 6 AND lessondate OR practicaldate OR interviewstart  BETWEEN curdate() AND      '2014-12-21'
GROUP BY staff_id

课程日期和实际日期都是 DATE 格式,并且 interviewstart 是 DATETIME(我知道这并没有太大的区别,但你知道。) 这返回了我见过的最混乱的桌子,而且绝对没有得到正确的信息。 我期待的结果是这样的:

staff_id    lesson date     practical date  interviewstart
6           2014-12-18      
6                           2014-12-19
6                                           2014-12-15 13:00:00

如果有任何意义,它只是一个基本列表。

请有人在这里尝试帮助我,我通常很擅长寻找解决问题的方法,但我的 MYSQL 还达不到标准! (如果代码显示不正确也很抱歉,我尽力了!)

【问题讨论】:

  • 很好的解释,但所有表格都有一些示例数据可以使问题在理解和发现问题方面变得更好。
  • 感谢您的快速反馈,我正在寻找的基本结果是一种显示一个工作人员范围内的所有日期/日期时间的方法(每个表中的外键)。
  • 请在每张表内贴一些相关数据。如果您想要一个出色的国王解决方案,如果您提供每个表中的数据,它将变得更容易/可能
  • 您的表之间缺少连接,因此我怀疑您是否会轻易解决此问题。简单规则:从不from 子句中使用逗号。
  • 感谢大家的反馈,我正在根据 E. Uta 下面的回答制定更新的解决方案,我应该提出一个新问题还是更新这篇文章? (这里是新人,所以想尽可能地遵守礼仪。)

标签: mysql database date join between


【解决方案1】:

您错误地使用了 OR 运算符。试试这个:

SELECT staff.staff_id, lname, interviewstart, lessondate, lessontime, prac_date, prac_time
FROM staff, interviews, lessons, practicaltests
WHERE staff.staff_id = 6 AND (lessondate BETWEEN curdate() AND '2014-12-21' OR practicaldate BETWEEN curdate() AND '2014-12-21' OR interviewstart  BETWEEN curdate() AND '2014-12-21') GROUP BY staff_id

【讨论】:

  • 刚用这个,我们有进步了!它不再制作大而杂乱的列表,但它现在打印出一行来找到正确的工作人员和姓氏。然而,它返回的面试、实习日期和上课日期都只是这些表中的第一个值。
【解决方案2】:

需要考虑的事项:
- 使用标准连接语法([INNER/LEFT/RIGHT] JOIN table ON join_condition
- 为正确的逻辑使用括号并克服运算符优先级(因为 AND 在 OR 之前进行评估)
- 如果您使用 GROUP BY,则 GROUP BY 子句中包含的所有列必须出现在选择列表中(反之亦然)。

下面的查询应该对你有帮助(注意你需要检查加入条件)

SELECT staff.staff_id, lname, interviewstart, lessondate, lessontime, prac_date, prac_time
FROM staff
LEFT JOIN interviews
    ON staff.staff_id = interviews.staff_id
LEFT JOIN lessons
    ON staff.staff_id = lessons.staff_id
LEFT JOIN practicaltests
    ON staff.staff_id = practicaltests.staff_id 
WHERE staff.staff_id = 6 
AND (
    lessons.lessondate BETWEEN curdate() AND '2014-12-21'
    OR practicaltests.practicaldate BETWEEN curdate() AND '2014-12-21'
    OR interviews.interviewstart BETWEEN curdate() AND '2014-12-21'
)

注意:例如,您可以使用 curdate()+7 代替硬编码的日期。这意味着将当前日期增加 7 天。

【讨论】:

  • 感谢您的帮助。这无疑带​​来了积极的变化。现在的主要问题是整个 interviewstart 列都显示“NULL”(但特别是这个工作人员没有任何面试,所以可能是正确的),并且课程和实际测试结果在工作人员的所有结果之间交替出现。
  • @hateprogramming,好的,你能更具体地说明什么是不正确的吗?是否可以在问题中添加更多示例数据并说明原始表格中需要什么以及不需要什么?当然,不是真实数据。
  • 好的,基本结果是一个可用于查看工作人员时间表的列表。他可以参与的三个领域是面试、课程和实践测试。我将使用的字段是 staff_id (INT)、lname (VARCHAR)、interviewstart (DATETIME)、lessondate (DATE)、lessontime (TIME)、prac_date (DATE)、prac_time (TIME)。错误的第一件事是它在同一行打印课程和实践测试,而不是在 17 日 12:00 显示例如课程,然后为第二天的实践测试创建新行。另一个问题是它不止一次显示结果。
  • 我还会使用 curdate()+7 作为 BETWEEN curdate()+7 还是会改变?
  • 你应该使用它,例如:BETWEEN curdate() and curdate()+7
猜你喜欢
  • 1970-01-01
  • 2011-09-18
  • 1970-01-01
  • 2012-05-03
  • 2021-11-19
  • 1970-01-01
  • 1970-01-01
  • 2011-08-10
  • 2015-05-20
相关资源
最近更新 更多