Фильтровать элементы SQL с соседним идентификатором - PullRequest
0 голосов
/ 22 сентября 2018

Я не знаю, как правильно сформулировать этот вопрос в заголовке.

Предположим, у меня есть таблица 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 сделать это за один вызов?Желательно напрямую использовать QuerySets Django?

EDIT: Идея состоит в том, что на самом деле я хочу отфильтровать те слова, которые есть во втором QuerySet.Что-то вроде:

Word.objects.filter(text__of__previous__word='Hello', text='Max')

Ответы [ 2 ]

0 голосов
/ 22 сентября 2018

Если под «1 выкл» вы имеете в виду, что разница точно равна 1, то вы можете сделать:

select w.*
from w
where w.id in (select w2.id + 1 from words w2 where w2.text = 'Hello');

lag() также является очень разумным решением.Это похоже на прямое толкование вашего вопроса.Если у вас есть пробелы (и намерение составляет + 1), то lag() немного сложнее.

0 голосов
/ 22 сентября 2018

В обычном 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 добавляет столбец с текстом предыдущей строки. Таким образом, вы можете фильтровать по этомутекст в подзапросе.

demo: db <> fiddle


Я на самом деле не в Django, но документация означает, что вВ версии 2.0 была добавлена ​​функциональность для оконной функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...