我对我的SQL有点生疏,并且在查询中遇到了一个小问题。在我们的应用程序中,我们有两个相对表来解决这个问题。有条目,每个条目有 N 个步骤。
我们正在尝试优化查询,因此我们不是一直要求所有条目,而是只要求上次检查后更新的条目。可能有很多步骤,所以这个查询只是应该返回条目和一些步骤摘要数据,如果需要,我们可以单独查询步骤。
条目开始时间和更新时间分别从第一个和最近的流程步骤时间计算。我们还必须将进入状态组合在一起。
这是我们在python中构建它的查询,因为它似乎更容易阅读:
statement = 'SELECT e.serial_number, ' +
'e.description, ' +
'min(p.start_time) begin_time, ' +
'group_concat(p.status) status, ' +
'max(p.last_updated) last_updated, ' +
'FROM entries e ' +
'LEFT OUTER JOIN process_steps p ON e.serial_number = p.serial_number ' +
# if the user provides a "since" date, only return entries updated after
# that date
if since is not None:
statement += ' WHERE last_updated > "{0}"'.format(since)
statement += ' GROUP BY e.serial_number'
我们遇到的问题是,如果我们应用该WHERE
子句,它也会过滤流程步骤。因此,例如,如果我们有两个条目的情况:
Entry: 123 foo
Steps:
1. start time 10:00, updated 10:30, status completed
2. start time 11:00, updated 11:30, status completed
3. start time 12:00, updated 12:30, status failed
4. start time 13:00, updated 13:30, status in_progress
Entry: 321 bar
Steps:
1. start time 01:00, updated 01:30, status completed
2. start time 02:00, updated 02:30, status completed
如果我们在没有 where 的情况下查询,我们将获得所有条目。因此,对于这种情况,它将返回:
321, bar, 01:00, "completed,completed", 02:30
123, foo, 10:00, "completed,completed,failed,in_progress", 13:30
如果我有 12:15 的时间,那么它只会返回以下内容:
123, foo, 12:00, "failed,in_progress", 13:30
在该结果中,开始时间来自步骤 3,状态仅来自步骤 3 和 4。我正在寻找的是整个条目:
123, foo, 10:00, "completed,completed,failed,in_progress", 13:30
所以基本上,我想根据该last_updated
值过滤最终结果,但它目前也在过滤连接结果,这会抛出begin_time
、last_updated
和status
值,因为它们是用部分步骤集计算的。任何想法如何修改查询以获得我想要的东西?
编辑:
这里似乎也可能存在一些命名问题。我在示例代码中使用的名称等于或类似于我们在代码中实际拥有的名称。如果我们将max(p.last_updated) last_updated
更改为max(p.last_updated) max_last_updated
,并将WHERE
子句也更改为使用max_last_updated
,我们会得到OperationalError: misuse of aggregate: max()
我们还尝试在其中添加AS
语句,没有区别。
创建一个子查询,该子查询首先选择更新的进程:
SELECT whatever you need FROM entries e
LEFT OUTER JOIN process_steps p ON e.serial_number = p.serial_number
WHERE e.serial_number in (SELECT distinct serial_number from process_steps
WHERE last_updated > "date here")
GROUP BY e.serial_number
您可以使用having
子句执行此操作:
SELECT . . .
FROM entries e LEFT JOIN
process_steps ps
ON e.serial_number = ps.serial_number
GROUP BY e.serial_number
HAVING MAX(ps.last_updated) > <your value here>;