postgresql - 在 Postgres 中对子元素进行动态排序的查询
问题描述
我有一个如下所示的数据集(PostgresQL 版本 11),我想在其中添加一个带有小数点的排序列,以便我可以轻松地在我的可视化中映射父子树。
我们可以做到这一点的任何方法或查询,尝试使用行号和排名,但这无济于事。
数据集:
Parent Child
Vitamine Vitamine
Vitamin D Vitamin D
Vitamin D Vitamin D3
Vitamin D Vitamin D K2
Vitamin D D3
Vitamin D Vitamin D 1000
Vitamin D Vitamin D 10000
Vitamin D Vitamin D 20000
Vitamin K2 Vitamin K2
Vitamin K2 Vitamin K
Vitamin K2 Vitamin K2 Mk7
Vitamin C Vitamin C
预期输出
Parent Child Sort_order
Vitamine Vitamine 1
Vitamin D Vitamin D 2
Vitamin D Vitamin D3 2.1
Vitamin D Vitamin D K2 2.2
Vitamin D D3 2.3
Vitamin D Vitamin D 1000 2.4
Vitamin D Vitamin D 10000 2.5
Vitamin D Vitamin D 20000 2.6
Vitamin K2 Vitamin K2 3
Vitamin K2 Vitamin K 3.1
Vitamin K2 Vitamin K2 Mk7 3.2
Vitamin C Vitamin C 4
解决方案
考虑以下表模式:
create table vitamins (
id serial primary key,
parent_id integer,
name varchar(64),
index smallint
);
使用以下数据:
insert into vitamins (id, parent_id, name, index) values
(1, null, 'Vitamine', 1),
(2, null, 'Vitamin D', 2),
(3, 2, 'Vitamin D3', 1),
(4, 2, 'Vitamin D K2', 2),
(5, 2, 'D3', 3),
(6, 2, 'Vitamin D 1000', 4),
(7, 2, 'Vitamin D 10000', 5),
(8, 2, 'Vitamin D 20000', 6),
(9, null, 'Vitamin K2', 3),
(10, 9, 'Vitamin K', 1),
(11, 9, 'Vitamin K2 Mk7', 2),
(12, null, 'Vitamin C', 4)
;
我们可以通过以下查询获得您想要的预期输出:
WITH RECURSIVE recursive_vitamins(id, parent_id, index, parent_name, name, ref, sort) AS (
SELECT c.id, c.parent_id, c.index, c.name, c.name, c.index::text, lpad(c.index::text, 3, '0')
FROM vitamins c
WHERE parent_id is null
UNION ALL
SELECT c.id, c.parent_id, c.index, rc.parent_name, c.name,
CASE WHEN rc.ref = '' THEN c.index::text
ELSE (rc.ref || '.' || c.index)
END, (rc.sort || '.' || lpad(c.index::text, 3, '0'))
FROM vitamins c, recursive_vitamins rc
WHERE c.parent_id = rc.id
)
SELECT
parent_name AS parent,
name AS child,
ref AS sort_order
FROM recursive_vitamins
ORDER BY sort;
结果:
parent child sort_order
Vitamine Vitamine 1
Vitamin D Vitamin D 2
Vitamin D Vitamin D3 2.1
Vitamin D Vitamin D K2 2.2
Vitamin D D3 2.3
...
等等,这里发生了什么?
因此,我们创建了一个递归 CTE,允许查询引用它自己的输出。在WITH
查询中,我们首先选择所有父母(parent_id is null
)然后我们选择所有引用的孩子parent_id
。
该ref
字段是父索引和子索引的串联。该sort
字段也指代index
,但它将with填充到总长度为 3。您可以将其省略,而只是,但如果您有>= ,则顺序将变为我猜您不想要的顺序.index
0
order by ref
index
10
1, 10, 10.1, 2
推荐阅读
- javascript - 如何关闭 AMP 侧边栏的动画
- postgresql - PostgreSQL:文本中的数组到数组
- bash - 正则表达式仅过滤特定字符串的第一次出现
- botframework - 使用 Microsoft Teams Bot 转发消息
- php - 使用PHP将数据从数据库导出到sql文件
- javascript - 尝试比较数组并使用 if else 语句对它们进行切片
- json - 在使用 tkinter 制作的应用程序中打开并保存为用户设置的 Json 配置文件
- reactjs - 将所有请求发送到 index.html,除了某些扩展
- powershell - 使用 Powershell 检查字符串中的特定单词是否包含大写字母
- javascript - 如何在 phpfox 4.7.7 中使用 intro.js