我有以下选择查询
$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 ";
答案 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