SQLite查询WHERE和OUTER JOIN

时间:2019-04-12 14:58:26

标签: sql sqlite

我对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_timelast_updatedstatus个值,因为它们是通过部分步骤来计算的。有什么想法如何修改查询以在这里得到我想要的东西吗?

编辑:

似乎这里也可能存在一些命名问题。我在示例代码中使用的名称与我们在代码中实际使用的名称相同或相似。如果我们将max(p.last_updated) last_updated更改为max(p.last_updated) max_last_updated,并将WHERE子句也更改为使用max_last_updated,我们将得到OperationalError: misuse of aggregate: max()我们也尝试添加{{1} }语句中没有任何区别。

2 个答案:

答案 0 :(得分:2)

创建一个子查询,该子查询首先选择更新的进程:

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

答案 1 :(得分:1)

您可以使用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>;
相关问题