- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
大多数描述 Postgres 中的 SELECT TOP ...
查询的资源都说您应该使用 LIMIT
代替,可能使用 ORDER BY
子句,如果您需要按某种顺序选择顶部元素。
如果您需要从递归查询中选择前 N 个元素,您会怎么做,其中没有排序,并且查询有可能在没有递归的情况下返回少于 N 行(以便 TOP
部分是确保结果集至少 N 行所必需的,而 LIMIT
可以允许更少的行)?
我的具体用例是对 dynamic SQL pattern for selecting a random subsample of a table 的修改.
这是一个link to the sql source我的修改。最简单的事情是查看那里定义的最终函数,_random_select
。它非常接近上述链接,但已被修改为在输入表和输出结果集中是多态的,并且正确地考虑了只返回输入表中已经存在的列的需要(另一个动态 SQL hack 以从最终结果集中排除临时 row_number
结果)。
虽然有点碍眼,但它是我所拥有的最接近可重现示例的东西。如果您使用 _random_select
并尝试从大于 4500 行的表中获取大约 4500 行的内容,您开始看到更小的结果集的可能性很高,并且随着您增加您的大小,情况只会变得更糟所需的样本(因为随着所需样本的增加,重复项的出现会变得更糟)。
请注意,在我的修改中,我没有使用此链接中的 _gaps
技巧,如果某个索引列中存在间隙,则意味着过度采样以抵消采样效率低下。那部分与这个问题无关,在我的例子中,我使用 row_number
来确保有一个没有可能间隙的整数列。
CTE 是递归的,以确保如果 CTE 的第一个非递归部分没有为您提供足够的行(因为 UNION
删除了重复项),那么它将继续通过 CTE 的另一轮递归调用返回,并继续处理更多结果,直到您获得足够的结果。
在链接示例中,使用了 LIMIT
,但我发现这不起作用。该方法返回的结果较少,因为 LIMIT
只是一个最多 N 行 保证。
如何保证至少 N 行?选择 TOP
N 行似乎是执行此操作的自然方式(因此递归 CTE 必须继续前进,直到它获得足够的行来满足 TOP
条件),但这在 Postgres 中不可用。
最佳答案
这对于评论来说太长了,但可以提供有关我现有查询的情况的信息。来自documentation on recursive query evaluation ,递归查询将采取的步骤是:
Evaluate the non-recursive term. For UNION (but not UNION ALL), discard duplicate rows. Include all remaining rows in the result of the recursive query, and also place them in a temporary working table.
So long as the working table is not empty, repeat these steps:
a. Evaluate the recursive term, substituting the current contents of the working table for the recursive self-reference. For UNION (but not UNION ALL), discard duplicate rows and rows that duplicate any previous result row. Include all remaining rows in the result of the recursive query, and also place them in a temporary intermediate table.
b. Replace the contents of the working table with the contents of the intermediate table, then empty the intermediate table.
所以我在评论中的直觉(在尝试使用 UNION ALL
之后)大部分是在正确的轨道上。
正如文档所述,这实际上只是一种迭代,它重新使用先前的非递归结果部分来代替递归名称递归部分。
所以它更像是一个不断缩小的过程,其中用于替代递归名称的“工作表”仅包含最近一轮递归结果的特定子集,不是先前结果的重复.
这是一个例子。假设我们在表中有 5000 行,我们想要对 3000 个唯一行进行采样,一次对 1000 个(可能不是唯一的)样本进行递归采样。
我们做了第一批 1000 个,删除重复项,所以我们最终得到大约 818 个非欺骗 based on the binomial distribution对于这些大数(N=5000,m = 1000,k=1,重新排列项以避免溢出)。
这 818 个成为工作表,这个结果集被代入作为我们下一次传递的递归项。我们绘制了另一组大约 818 个唯一行,但在与工作表中的原始 818 行进行比较时,必须删除重复项 (UNION
)。两次不同的 818 随机抽取将有明显的重叠(平均大约 150),因此所有这些都将被丢弃,而保留的任何新唯一行将成为新工作表。
因此,您将在第一次抽取时添加大约 818 个唯一样本,然后工作表缩小,第二次抽取时将增加约 650 个,工作表缩小,...您一直这样做,直到达到所需的总样本总数(在本例中为 3000)或工作表最终为空。
一旦工作表足够小,在下一次抽取 1000 时很有可能复制其中的所有内容,此时工作表变空,递归终止。
对于抽取 3000 个样本,您可能能够将此工作表更新足够多次。但是当您从 3000 接近表的总大小 5000 时,概率会非常快地缩小到几乎为零。
因此,这不是一个优化器问题,它与较小的结果集短路,这实际上是 Postgres 中实现“递归”的特定方式的问题——它实际上不是递归,而是在集合上运行的简单迭代当前工作表与最近的递归查询结果集之间的差异。对于像这样的随机抽样,工作表将随着每次迭代非常快地变小,直到由于选择重复项的可能性很高而极有可能为空。
关于sql - 如何保证 Postgres 中的递归 CTE 至少返回 N 行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36119189/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwar
有没有办法保证您的系统托盘图标被删除? 添加系统托盘图标: Shell_NotifyIcon(NIM_ADD, &m_tnd); 删除系统托盘图标: Shell_NotifyIcon(NIM_DELE
是否保证(-x) % m,其中x和m在c++中为正standard (c++0x) 为负数,等于 -(x % m)? 我知道它在我知道的所有机器上都是正确的。 最佳答案 除了Luchian的回答,这是
可能还有其他方法可以作为示例,但这不是我要问的重点。 我正在这样做: (future (clojure.java.shell/sh "sleep" "3" :dir "/tmp")) 启动对Shell
可以使用 XREAD(或者可能是另一个命令)以原子方式检测数据是否写入 Redis 流? 进一步来说: 假设您在一个进程中将一些数据添加到 Redis 流中,并看到数据已通过某个自动生成的 key 成
Kotlin 协程是否提供任何“发生之前”保证? 例如,在这种情况下,写入 mutableVar 和随后在(可能)其他线程上读取之间是否存在“发生之前”保证: suspend fun doSometh
我正在开发一个跟踪行程的应用程序。在搜索了这件事之后,我得出结论,实现这一点(持续跟踪用户的位置)的最好方法是使用前台服务。在某些情况下工作得很好,但在其他一些情况下(即使关闭 DOZE),我得到一些
我正在使用 ORM (sqlalchemy) 从 PG 数据库中获取数据。我想避免在我手工编写的 SQL 语句中指定所有表列名称*。 到目前为止,我的假设是返回的列按照用于创建数据库表的 DDL 语句
在 setState 的文档中这样说: setState() does not immediately mutate this.state but creates a pending state tr
我有一个与不同硬件接口(interface)的简单应用程序。对于每个硬件,我针对一个独特的监视器函数生成了一个 pthread_t,总共有 6 个线程:1 个管理线程和 5 个工作线程。 每个线程都有
目前,我有 private ThreadLocal shortDateFormat = new ThreadLocal() { @Override protected DateFormat i
我有一个使用 SolrCloud 将文档写入 Solr 的 Java 作业。输入数据被转换为不同实体的映射,然后将每个实体写入与其实体类型对应的 Solr 集合。 我的代码如下: public voi
我们使用嵌入式设备通过串行到以太网转换器将数据包从串行端口发送到服务器。我们使用的一家制造商 Moxa 将始终以与构建它们相同的方式发送数据包。意思是,如果我们构建一个大小为 255 的数据包,它将始
我是从 C++ 转到 Java 的。在 C++ 世界中,我们关注异常安全,并注意到变元器可以在变元器本身或其委托(delegate)的方法抛出异常时提供不同的保证(最小、强、不抛出)。实现具有强异常保
我想将来自 SAAJ 的 SOAPConnectionFactory 和 MessageFactory 类与多个线程一起使用,但事实证明我不能假设它们是线程安全的。一些相关的帖子: javax.xml
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 5 年前。 Improve
关于正确性,我找不到以下代码片段没有设计缺陷的证据/反证据。 template class MyDirtyPool { public: template std::size_t ad
对于这个问题,我找到了不同的答案,我知道一定有一个确定的答案。 C 中四种主要数据类型的最小分配内存大小是多少? int , double , float , 和 char是我在想什么。做 signe
我正在使用 Kafka Producer,我的应用程序将具有相同键的各个 ProducerRecords 发送到单个分区中,然后这些 ProducerRecords 在发送到代理之前进行批处理(使用
您好,我是服务器端编程 (java) 的新手,正在阅读 SendRedirect 与 Forward 之间的区别。来自 Post-redirect-get pattern它解释说这将阻止通过点击刷新按
我是一名优秀的程序员,十分优秀!