SQL-запрос на заказ по специальному условию - PullRequest
0 голосов
/ 11 июня 2019

У меня есть таблица A, как показано ниже: -

id parent_id
1    null
2    1
3    null
4    1
5    3
6    1
7    null
8    7
9    777

Я хочу написать запрос, который возвращает порядок, как показано ниже: -

id parent_id
9    777
1    null
2    1
4    1
6    1
3    null
5    3  
7    null
8    7

Если в строке есть parent_id, которого нет в таблице A, он идет первым. Тогда все идентификаторы с нулевыми parent_id являются вторыми, и если есть идентификатор, ссылающийся на другой идентификатор, или parent_id не является нулевым, чтобы быть точным, они упорядочиваются чуть ниже строки parent_id.

Как бы я сделал это в postgresql? Это то, что я придумала до сих пор и хотела вторую пару глаз и возможные улучшения. Случай 1 - когда строка имеет parent_id, но parent_id отсутствует в таблице A, она имеет наивысший приоритет. Случай 2 - когда строка не имеет parent_id, тогда ее приоритет 2. Случай 3 - когда у строки есть parent_id, тогда ее приоритет 3.

Происходит следующее: CASE 2 перечисляет все документы, соответствующие CASE 2, а затем перечисляет все документы, соответствующие CASE 3, которые мне не нужны.

select id, parent_id from A 
order by 
case 
  when parent_id is not null and parent_id not in ( select id from A) then 1
  when parent_id is null then 2 
  when parent_id is not null and parent_id in ( select id from A) then 3 
  else parent_id END asc limit 100;

Как бы я сделал это в sqlalchemy? Еще не подумал об этом. Но как только я выполню запрос sql, преобразование его в sqlalchemy будет довольно простым.

Я мог бы легко обработать объект sqlalchemy и упорядочить их, используя некоторые для циклов for и, если еще условия, но я хотел узнать, как это сделать на уровне запросов sql.

БОНУС: Я хочу отсортировать их по дате, скажем, созданной в. После того, как приведенная выше логика дает мне правильный порядок, примените другой порядок, который был создан через, с сохранением первого порядка.

Буду рад некоторой обратной связи. Благодаря.

1 Ответ

1 голос
/ 11 июня 2019

У ваших выборочных данных есть только один уровень родителей, поэтому вы можете сделать:

select t.*
from t left join
     t tp
     on t.id = t.parent_id
order by ( tp.id is null and t.parent_id is not null) desc,
         coalesce(parent_id, id),
         ( t.parent_id is null ) desc,
         t.id  -- the final sorting criterion

Здесь - это дБ скрипка.

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