Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 仅返回数组包含元素的第一行,可能会忽略前面看到的任何元素_Postgresql - Fatal编程技术网

Postgresql 仅返回数组包含元素的第一行,可能会忽略前面看到的任何元素

Postgresql 仅返回数组包含元素的第一行,可能会忽略前面看到的任何元素,postgresql,Postgresql,给定以下数据集: | page | sentence_ids | |------|--------------| | 1 | { 1, 2, 3 } | | 2 | { 1, 2 } | | 3 | { 3, 4 } | 我想做一个查询,返回句子id最先出现的页面。最好是句子ID在数据集中只出现一次,并且页数最少。在这种情况下: | page | sentence_ids | |------|--------------| | 1 | { 1, 2,

给定以下数据集:

| page | sentence_ids |
|------|--------------|
| 1    | { 1, 2, 3 }  |
| 2    | { 1, 2 }     |
| 3    | { 3, 4 }     |
我想做一个查询,返回句子id最先出现的页面。最好是句子ID在数据集中只出现一次,并且页数最少。在这种情况下:

| page | sentence_ids |
|------|--------------|
| 1    | { 1, 2, 3 }  |
| 3    | { 4 }        |
这可能吗?这种关系是非规范化的,因为页面可以以10000结尾,句子可以以100000结尾


现在我们加载包含所有句子的所有页面,并在代码中进行筛选。效率极低。希望有人能帮上忙。

唯一实用的方法*是首先
取消
语句ID的数组
,然后选择
页面、句子
的组合,使后者与最低页面相匹配;您可以通过一个窗口函数对句子进行分区,并在按页面排序后找到一个秩来实现这一点。
rank=1的记录是兴趣的组合。然后将结果聚合回数组:

SELECT page, array_agg(sentence)
FROM (
  SELECT page, sentence, rank() OVER (PARTITION BY sentence ORDER BY page) AS rnk
  FROM (
    SELECT page, unnest(sentence_ids) AS sentence
    FROM page_sentences) p_s
  ) p_s_r
WHERE rnk = 1
GROUP BY page;
考虑到数据的大小,这可能不是一个很快的解决方案,但它很可能比提取所有数据然后在代码中过滤要好

  • “实用”在这里被松散地定义为“任何避免遵循克雷格建议的东西”。(对不起,克雷格…)

因此,您需要一个自定义窗口函数,该函数将集合中的所有可见元素累加起来,然后在每一行上只发出新元素,如果没有唯一元素,则在空数组中发出null/值。然后在
FROM
中将该调用包装为子查询,其中外部查询过滤掉没有新句子的行。自定义窗口功能是最难的一点;我认为此时您唯一的选择是用C编写。如果您愿意稍微滥用API,您可以用PL/Python、PL/Perl等编写一个普通的非窗口函数,声明它
VOLATILE
,并将设置的数据隐藏在解释器命名空间中的某个地方,在调用之间可以访问该数据。这很有意思,但这(或C级的等价物)是人们在有窗口功能之前经常做的事情。太棒了!p_s和p_s_r代表什么?
FROM
子句中的子查询需要别名,即使它从未用于引用列。p_s仅仅代表(页面、句子)组合,p_s_r加上排名。