PostgreSQL:json词汇概述,窗口函数。。。递归?
我有一本进入PostgreSQL 9.3的“字典”。我想得到所有的术语,在每页最多30个术语的页面之间,将它们分成三个字符(前三个字符)。因此,页面之间不应出现任何三元组,例如,第一个页面应包含术语“aaa”到“aaf”,第二个页面应包含术语“aag”到“aan”,但任何页面都不应包含“三元组集合”的一部分 到目前为止,我有以下疑问:PostgreSQL:json词汇概述,窗口函数。。。递归?,json,postgresql,postgresql-9.3,recursive-query,window-functions,Json,Postgresql,Postgresql 9.3,Recursive Query,Window Functions,我有一本进入PostgreSQL 9.3的“字典”。我想得到所有的术语,在每页最多30个术语的页面之间,将它们分成三个字符(前三个字符)。因此,页面之间不应出现任何三元组,例如,第一个页面应包含术语“aaa”到“aaf”,第二个页面应包含术语“aag”到“aan”,但任何页面都不应包含“三元组集合”的一部分 到目前为止,我有以下疑问: WITH results AS ( WITH terms AS ( WITH triples AS ( -- 1. tri
WITH results AS (
WITH terms AS (
WITH triples AS (
-- 1. triples with cumulative numbers of appearances:
SELECT
LOWER(substring("term" FROM 1 FOR 3)) AS triple,
ROW_NUMBER() OVER(PARTITION BY LOWER(substring("term" FROM 1 FOR 3))) AS rnum
FROM terms
GROUP BY triple, "term"
)
-- 2. GROUPs by rnum, removes triple duplicates:
SELECT
triples.triple,
MAX(triples.rnum) AS amount
FROM triples
GROUP BY triples.triple
)
-- 3. makes { "triple": triple, "amount": amount },
-- assigns "page number" (~30 per page):
SELECT
COALESCE(substring(terms.triple FROM 1 FOR 1), '') AS first,
('{ "triple": "' || COALESCE(terms.triple, '') || '", "amount": ' || terms.amount || ' }')::json AS terms,
(sum((terms.amount)::int) OVER (ORDER BY terms.triple)) / 30 AS chunk
FROM terms
GROUP BY first, terms.triple, terms.amount
ORDER BY first, terms.triple
)
-- 4. collects "page" triples into rows:
SELECT
first,
COALESCE(json_agg(results.terms), ('{ "triple" :' || NULL || ', "amount":' || 1 || '}')::json) AS triplesdata,
sum((results.terms->>'amount')::int) AS sum,
chunk
FROM results
GROUP BY first, chunk
ORDER BY results.first, json_agg(results.terms)->0->>'triple'
明确地说,SELECT#1为我提供了:
triple | rnum
--------+------
аар | 1
аба | 1
абе | 1
абе | 2
аби | 1
аби | 2
абл | 1
...
first | triplesdata | sum | chunk
-------+-----------------------------------------------+-----+-------
а | [{ "triple": "аар", "amount": 1 } ...(others) | 28 | 0
a | [{ "triple": "аве", "amount": 5 } ...(others) | 30 | 1
...
д | [{ "triple": "доб", "amount": 69 }, ... | 89 | 138
...
选择#2将提供所有三元组以及以它们开头的单词数量:
triple | amount
--------+--------
аар | 1
аба | 1
абе | 2
аби | 2
абл | 1
або | 1
абс | 1
...
SELECT#3为我提供了几乎相同的信息,但现在三元组是json
s,并添加了chunk number列:
first | terms | chunk
-------+----------------------------------+-------
а | { "triple": "аар", "amount": 1 } | 0
а | { "triple": "аба", "amount": 1 } | 0
а | { "triple": "абе", "amount": 2 } | 0
а | { "triple": "аби", "amount": 2 } | 0
а | { "triple": "абл", "amount": 1 } | 0
а | { "triple": "або", "amount": 1 } | 0
а | { "triple": "абс", "amount": 1 } | 0
...
整个查询给了我:
triple | rnum
--------+------
аар | 1
аба | 1
абе | 1
абе | 2
аби | 1
аби | 2
абл | 1
...
first | triplesdata | sum | chunk
-------+-----------------------------------------------+-----+-------
а | [{ "triple": "аар", "amount": 1 } ...(others) | 28 | 0
a | [{ "triple": "аве", "amount": 5 } ...(others) | 30 | 1
...
д | [{ "triple": "доб", "amount": 69 }, ... | 89 | 138
...
我可以用这个;然而,有些数据块包含太多的数据——有些三元组应该分成“四元组”和“多元组”
我编写了Python脚本,它递归地完成这项工作
但是我很忙:可以在PostgreSQL中执行这个递归工作吗?
还有另一个问题——terms.term
列的最佳索引(-es?)
还有一个问题:我做错了什么我对sql有些陌生
更新:到目前为止没有被接受的答案,因为我的问题没有答案。是的,我现在正在使用python脚本。但是我想得到一些答案。我最好的答案是,你不应该尝试用SQL而不是Python来做这件事。SQL在多级递归方面不太好(您可以愉快地在查询中执行查询,但不能执行任意深度嵌套的查询) SQL被设计成“声明性的”——你说你想要什么,数据库就会知道如何给你。这就是为什么您可以检查复杂查询的“计划”,以了解如何检索数据。当您的代码像上面那样使用
和
时,您已经达到了一个临界点,即为了向SQL解释器表达您想要的内容,您必须重新猜测中间步骤是什么。这意味着您处于一种两败俱伤的局面:解释器没有足够的灵活性以优化的方式检索数据,但您正在用一种复杂的语言表达计算步骤,这种语言最适合表达您想要的结果
另一方面,Python或许多函数式语言都是专门为使这样的任务能够快速而优雅地表达而设计的。你会发现自己是在使用材料,而不是反对材料
这是一个有趣的问题。如果您认为您的性能/基础架构要求意味着在数据库服务器之外很难完成此任务,请务必再次发帖。我最好的回答是,您不应该尝试在SQL中而不是使用Python来完成此任务。SQL在多级递归方面不太好(您可以愉快地在查询中执行查询,但不能执行任意深度嵌套的查询) SQL被设计成“声明性的”——你说你想要什么,数据库就会知道如何给你。这就是为什么您可以检查复杂查询的“计划”,以了解如何检索数据。当您的代码像上面那样使用
和
时,您已经达到了一个临界点,即为了向SQL解释器表达您想要的内容,您必须重新猜测中间步骤是什么。这意味着您处于一种两败俱伤的局面:解释器没有足够的灵活性以优化的方式检索数据,但您正在用一种复杂的语言表达计算步骤,这种语言最适合表达您想要的结果
另一方面,Python或许多函数式语言都是专门为使这样的任务能够快速而优雅地表达而设计的。你会发现自己是在使用材料,而不是反对材料
这是一个有趣的问题。如果您认为您的性能/基础架构要求意味着在数据库服务器之外很难完成此任务,请务必再次发布。我认为您可以使用附加模块“pg\u trgm”中的函数show\u trgm(text)大大简化查询:谢谢,我会在那里挖掘。我不知道如何简化。(你不需要“嵌套”cte,你可以用cte_1作为(…),cte_2作为(…),cte_3作为(…)一个接一个地编写
)选择…
CTEs可能这就是您正在寻找的。您能否在Pgadmin的SQL窗口中使用此嵌套表单发布完整的create table
语句,其中包括一些示例数据(理想情况下为insert into
语句),我可以选择(用鼠标)然后从最里面到最外面执行选择。谢谢,我稍后会尝试准备并发布一些测试数据。我想您可以使用附加模块“pg\u trgm”中的函数show\u trgm(text)来大大简化查询:谢谢,我会在那里挖掘。我不知道如何简化。(您不需要“嵌套”cte,您可以使用cte_1作为(…)、cte_2作为(…)、cte_3作为(…)依次编写,选择…
cte,这可能就是您要查找的内容。您是否可以发布完整的create table
语句,其中包含一些示例数据(理想情况下为insert-in
语句)在Pgadmin的SQL窗口中使用这个嵌套表单,我可以选择(我的意思是用鼠标)然后从最里面到最外面执行选择。谢谢,我稍后会尝试准备并发布一些测试数据。谢谢,但如果可能的话,我想知道如何在PostgreSQL中做到这一点。在这种情况下,我想尽可能多地退出RDBMS。只是为了学习。@brownian了解到有些东西不是装备ht方法也在学习中。您可以轻松地在Postgres中执行递归查询。谢谢,但我想知道如何执行此操作