sql - 使用每个表函数的一列来比较两个表函数的结果

标签 sql postgresql postgresql-9.3 set-returning-functions

根据说明here我创建了两个使用 EXECUTE FORMAT 并返回相同的 (int,smallint) 表的函数。

示例定义:

CREATE OR REPLACE FUNCTION function1(IN _tbl regclass, IN _tbl2 regclass, 
IN field1 integer) 
RETURNS TABLE(id integer, dist smallint)

CREATE OR REPLACE FUNCTION function2(IN _tbl regclass, IN _tbl2 regclass, 
IN field1 integer) 
RETURNS TABLE(id integer, dist smallint)

两个函数返回完全相同的行数。示例结果(将始终按距离排序):

(49,0)
(206022,3)
(206041,3)
(92233,4)

有没有办法比较同一行的两个函数之间的第二个字段的值,以确保两个结果相同:

例如:

SELECT
function1('tblp1','tblp2',49),function2('tblp1_v2','tblp2_v2',49)

返回类似:

(49,0)      (49,0)
(206022,3)  (206022,3)
(206041,3)  (206041,3)
(92233,4)   (133,4)

虽然我并不期望相同的结果(每个函数都是一个 topK 查询,并且我的关系被任意破坏/在第二个函数中进行了一些优化以获得更快的性能),但我可以确保这两个函数如果每行结果中的第二个数字相同,则返回正确的结果。在上面的例子中,我可以确保得到正确的结果,因为:

1st row 0 = 0,
2nd row 3 = 3,
3rd row 3 = 3,
4th row 4 = 4

尽管对于第四行,92233!=133

有没有办法只获取每个函数结果的第二个字段,以批量比较它们,例如像这样的东西:

SELECT COUNT(*)
FROM 
(SELECT
function1('tblp1','tblp2',49).field2,
function2('tblp1_v2','tblp2_v2',49).field2 ) n2
WHERE  function1('tblp1','tblp2',49).field2 != function1('tblp1','tblp2',49).field2;

我使用的是 PostgreSQL 9.3。

最佳答案

Is there a way to get only the 2nd field of each function result, to batch compare them?

以下所有答案均假设行按匹配顺序返回。

Postgres 9.3

通过 SRF 函数爆炸行的古怪功能,并行返回相同行数:

SELECT count(*) AS mismatches
FROM  (
   SELECT function1('tblp1','tblp2',49) AS f1
        , function2('tblp1_v2','tblp2_v2',49) AS f2
   ) sub
WHERE  (f1).dist <> (f2).dist;  -- note the parentheses!

行类型周围的括号对于消除可能的表引用的歧义是必要的。 Details in the manual here.

如果返回的行数不相同(这会完全破坏它),则默认为行的笛卡尔积。

Postgres 9.4

WITH ORDINALITY 动态生成行号

您可以使用 WITH ORDINALITY 即时生成行号,而无需依赖于 SELECT 列表中 SRF 函数结果的配对:

SELECT count(*) AS mismatches
FROM      function1('tblp1','tblp2',49)       WITH ORDINALITY AS f1(id,dist,rn)
FULL JOIN function2('tblp1_v2','tblp2_v2',49) WITH ORDINALITY AS f2(id,dist,rn) USING (rn)
WHERE  f1.dist IS DISTINCT FROM f2.dist;

这适用于每个函数的相同行数以及不同的行数(这将被视为不匹配)。

相关:

ROWS FROM逐行连接集合

SELECT count(*) AS mismatches
FROM   ROWS FROM (function1('tblp1','tblp2',49)
                , function2('tblp1_v2','tblp2_v2',49)) t(id1, dist1, id2, dist2)
WHERE  t.dist1 IS DISTINCT FROM t.dist2;

相关答案:

旁白:
EXECUTE FORMAT 不是一组 plpgsql 功能。 RETURN QUERY 是。 format()只是构建查询字符串的便捷函数,可以在 SQL 或 plpgsql 中的任何位置使用。

关于sql - 使用每个表函数的一列来比较两个表函数的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28808819/

相关文章:

postgresql - 如何传递 ENUM 变量作为 POSTGRESQL 函数的输入

node.js - 安装 nodej.js pg 模块问题(无法打开包含文件 : 'pg_config.h' )

postgresql - 在 PostgreSQL 中创建内存表?

postgresql - 尝试将 csv 文件导入 postgresql 时出现 "extra data after last expected column"

postgresql - 校验和与整页图像有什么关系?

mysql - 如何过滤掉因某一字段而异的相似记录组

sql - 在关系数据库中存储分层数据有哪些选项?

java - SQLStateConverter.handledNonSpecificException hibernate

sql - 匹配MySQL中的两列

PostgreSQL 如何检查我的函数是否仍在运行