首页 > 解决方案 > 按特殊条件排序的 SQL 查询

问题描述

我有一个如下表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 中,则它先行。然后所有带有 null parent_id 的 id 都排在第二位,如果有一个 id 引用了另一个 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 循环和 if else 条件对它们进行排序,但我想学习如何在 sql 查询级别上执行此操作。

奖励:我想通过创建日期对它们进行排序。在上面的逻辑给了我正确的顺序之后,应用另一个顺序,通过创建的顺序,保持第一个顺序。

希望得到一些反馈。谢谢。

标签: pythonsqlpostgresqlsqlalchemy

解决方案


您的样本数据只有一级深度的父级,因此您可以执行以下操作:

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

是一个分贝小提琴。


推荐阅读