在日期和小于日期之间左联接

Left Join Between Dates and Less Than

我有以下选择查询

 $sql="SELECT s1.*
 FROM schedulelocation s1
 LEFT JOIN schedulelocation s2
 ON (s1.uid=s2.uid AND s1.stp>s2.stp)
 WHERE s2.stp is NULL AND s1.uid=:s1_uid AND s1.thu=:s1_thu AND s1.start<=:s1_start AND s1.end>=:s1_end";  

这是我的 schedulelocation 数据(简化版)

  UID      STP     start         end         Mon    Tue      Thu     Comment
 T5632      P    2015-10-06   2015-11-05       1      1       1       Hello
 U4123      P    2015-09-05   2015-10-09       1      1       1       Apple
 T5632      O    2015-10-06   2015-10-10       1      1       1       Pear
 U4123      O    2015-10-29   2015-10-31       1      1       1       Orange       

假设日期是 2015-10-08 我希望从查询中得到以下答案

对于 uid T5632 的答案 "Pear" 对于 uid T4123,答案 "Apple"

ie 查询应检查所选日期(即 2015-10-08)是否位于 table 中的开始日期和结束日期之间,然后选择最低的字母表 "stp" . (它还必须确保这一天是星期四)

查询成功找到 Pear 但没有找到 uid T4123 的结果

U4123

的答案"Apple"你能帮我吗

编辑 - 我现在已经尝试 GROUP BY

 $sql="SELECT * FROM (SELECT * FROM schedulelocation WHERE thu=:thu AND start<=:start AND end>=:end ORDER BY stp ) AS cifstp GROUP BY uid ";        

您可以使用 ORDER BY 和 LIMIT 1,无需连接:

SELECT s1.*
FROM
  schedulelocation s1
WHERE
  s1.uid=:s1_uid AND s1.thu=:s1_thu
  AND s1.start<=:s1_start AND s1.end>=:s1_end
ORDER BY
  stp
LIMIT 1

请看一个fiddle here.

编辑

如果您想 运行 单个查询,是的,您需要使用 SELF JOIN。您的查询的问题是您必须在 JOIN 条件中添加所选日期的检查:

SELECT s1.*
FROM
  schedulelocation s1 LEFT JOIN schedulelocation s2
  ON s1.uid=s2.uid
     AND s1.thu=s2.thu
     AND :datea BETWEEN s2.start AND s2.end
     AND s1.STP>s2.STP
WHERE
  :dateb BETWEEN s1.start AND s1.end
  AND s1.thu=:thu
  AND s2.uid IS NULL

请看here.

有点调皮,但是你可以在字符串上使用MAX()MIN()...

(这应该比您的子查询解决方案更快。使用 EXPLAIN 检查。)

SELECT
    s1.*,
    MIN(Comment)
FROM schedule location AS s1
WHERE
    thu = 1 AND
    start <= '2015-10-08' AND
    end >= '2015-10-08'
GROUP BY
    uid