在日期和小于

时间:2015-10-08 20:56:59

标签: php mysql left-join

我有以下选择查询

 $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";  

这是我的日程安排数据(缩短版本)

  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,回答“梨” 对于uid T4123的答案是“Apple”

即查询应该检查所选日期(即2015-10-08)是否在表中的开始日期和结束日期之间,然后选择它可以的最低字母“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 ";        

2 个答案:

答案 0 :(得分:1)

您可以使用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

请查看小提琴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

答案 1 :(得分:0)

这有点顽皮,但你可以在字符串上使用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