首页 > 解决方案 > PostgreSQL - 按array_position排序并在另一列上不同

问题描述

我有一个看起来像这样的查询(实际查询和表更复杂)

SELECT item.other_uuid, item.uuid, category.name
FROM item, category
WHERE ...
ORDER BY array_position(ARRAY[{'CDX', 'KDJ', 'PLM', 'OLA', 'OWK', 'CAT'}]::uuid[], item.uuid), category.name;

这给了我一个按特定顺序(数组传递的 uuid 顺序)的类别名称列表。例如:

789 CDX "Cat D"
123 KDJ "Cat A"
456 PLM "Cat B"
123 OLA "Cat F"
456 OWK "Cat X"
123 CAT "Cat Z"

我想做的是在该查询中添加一个 DISTINCT ON 'item.other_uuid'。所以结果列表将是:

789 CDX "Cat D"
123 KDJ "Cat A"
456 CAT "Cat B"

我怎样才能做到这一点?Postgres 希望 ORDER BY & DISTINCT 匹配,但这不是我查询的正确顺序。

我试图将其设为子查询并在主查询中使用 DISTINCT 但未维护顺序...

标签: postgresqlsql-order-bydistinct-on

解决方案


这里有两个组件,为每组“other_uuid”选择哪个成员,以及这些选定行的显示顺序。如果您希望管理这两个内容,您可能需要一个内部查询和一个外部查询,每个用他们自己的 ORDER BY。

select * from (
   SELECT distinct on (other_uuid)other_uuid, uuid, name
   FROM ...
   ORDER BY other_uuid, array_position(ARRAY['CDX', 'KDJ', 'PLM', 'OLA', 'OWK', 'CAT']::text[], uuid), name
) foo order by array_position(ARRAY['CDX', 'KDJ', 'PLM', 'OLA', 'OWK', 'CAT']::text[], uuid);

array_position 表达式的重复是丑陋的。有一些方法可以避免它,但这些方法也很丑陋。


推荐阅读