我真的不知道如何在标题中正确陈述这个问题。
假设我有一个Word
表,如下所示:
| id | text |
| --- | --- |
| 0 | Hello |
| 1 | Adam |
| 2 | Hello |
| 3 | Max |
| 4 | foo |
| 5 | bar |
是否可以基于text
查询该表并接收主键(id)恰好为一的对象?
所以,如果我这样做
Word.objects.filter(text='Hello')
我得到一个包含行的QuerySet
| id | text |
| --- | --- |
| 0 | Hello |
| 2 | Hello |
但是我想要行
| id | text |
| --- | --- |
| 1 | Adam |
| 3 | Max |
我想我能做
word_ids = Word.objects.filter(text='Hello').values_list('id', flat=True)
word_ids = [w_id + 1 for w_id in word_ids] # or use a numpy array for this
Word.objects.filter(id__in=word_ids)
但这似乎并不太有效。有一个简单的SQL方法可以在一次调用中做到这一点吗?最好直接使用Django的QuerySet?
编辑:这个想法是,实际上我想过滤第二个QuerySet中的那些单词。像这样:
Word.objects.filter(text__of__previous__word='Hello', text='Max')
答案 0 :(得分:2)
在普通的Postgres中,您可以使用lag
窗口函数(https://www.postgresql.org/docs/current/static/functions-window.html)
SELECT
id,
name
FROM (
SELECT
*,
lag(name) OVER (ORDER BY id) as prev_name
FROM test
) s
WHERE prev_name = 'Hello'
lag
函数添加带有上一行文本的列。因此,您可以在子查询中按此文本进行过滤。
我不是真的很喜欢Django,但是documentation意味着,在2.0版中,已添加了窗口功能。
答案 1 :(得分:1)
如果“ 1 off”表示差异正好是1,则可以执行以下操作:
select w.*
from w
where w.id in (select w2.id + 1 from words w2 where w2.text = 'Hello');
lag()
也是一个非常合理的解决方案。这似乎是您问题的直接解释。如果您有差距(意图是+ 1
),那么lag()
会比较棘手。