这可能非常简单,但我想知道编写此查询的“最佳”或“标准”方式。
我有两张桌子。一个是具有任务名称和开始时间戳和结束时间戳的工作计划。此表由计划管理员提前填充。
UserId | task | startTime | endTime
joe | dishes | 2010-05-15 10:00 | 2010-05-15 14:00
joe | papers | 2010-05-15 14:00 | 2010-05-15 15:00
joe | trash | 2010-05-16 09:00 | 2010-05-16 10:00
joe |cooking | 2010-05-16 11:30 | 2010-05-16 13:30
第二个表是一个工作日志,其中包含每天工作的分钟数和日期戳。该表由员工填充。
UserId | date | timeLogged
joe | 2010-05-15 | 300
joe | 2010-05-16 | 180
我的应用当前的工作方式是首先查询workLog
表,看看用户是否已经记录了给定日期范围的小时数。如果查询返回0行,则对计划表进行第二次礼貌查询,以便预填表单,使用户更容易进行调整等。
我想要的是一次性执行的查询。问题是如果“first”为null,它应该只进行“第二次”查询,所以做任何连接或者如果空值对我来说似乎不正确,因为当workLog
表需要时它会合并两个查询的结果占上风。例如,如果用户在周二和周三生病,但是周一和周四的记录小时数,我不希望结果使用周一和周四的记录小时数以及周二和周三的预定小时数。但如果他那周每天都生病,可以用表格数据填写表格,因为用户不会(或者至少不应该)提交表格。
我可以考虑一种或两种方法,主要是使用第三种聚合查询和UNION
语句,但这似乎很草率。
以下是我想要合并的查询:
SELECT date, timeLogged
FROM workLog
WHERE userID = '$userid'
AND date BETWEEN $startDate AND $endDate
如果没有返回结果:
SELECT DATE(startTime) AS date,
SUM(TIME_TO_SEC(TIMEDIFF(startTime,endTime)))/60 AS timeLogged
FROM schedule
WHERE userID = '$userid'
AND date BETWEEN $startDate AND $endDate
GROUP BY DATE(startTime)
因此,在两个查询之后所遵循的任何函数都不需要知道结果来自哪个表。
答案 0 :(得分:2)
这些查询会返回不同的内容。如果按用户和日期加入它们,然后获取工作日志的重复行,则只能将它们组合成一个句子:
SELECT ws.UserId, ws.task, ws.startTime, ws.endTime, wl.timeLogged
FROM workSchedule ws
LEFT JOIN workLog wl ON ws.UserId=wl.UserId
AND DATE(ws.startTime)=wl.date
WHERE UserId='joe'
将返回:
UserId | task | startTime | endTime | timeLogged
joe | dishes | 2010-05-15 10:00 | 2010-05-15 14:00 | 300
joe | papers | 2010-05-15 14:00 | 2010-05-15 15:00 | 300
joe | trash | 2010-05-16 09:00 | 2010-05-16 10:00 | 180
joe |cooking | 2010-05-16 11:30 | 2010-05-16 13:30 | 180
joe | dishes | 2010-05-17 09:00 | 2010-05-17 13:30 | NULL
joe | papers | 2010-05-17 13:30 | 2010-05-17 15:00 | NULL
...并且只考虑startTime。 (你能看到像2010-05-17 23:30 — 2010-05-18 00:30
这样的范围吗?)
老实说,我认为这没有道理。我会将它们分开。