SQL查询按特殊条件排序

时间:2019-06-11 18:17:50

标签: python sql postgresql sqlalchemy

我有一个表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中,那么它将排在第一位。 然后,所有id为null的parent_id都是第二个,如果有一个ID引用了另一个id,或者parent_id不为null的话,它们的排序就在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 个答案:

答案 0 :(得分:1)

您的样本数据的父级只有一层,因此您可以这样做:

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

Here是数据库提琴。