使用每个函数的一列比较两个 table 函数的结果
Compare result of two table functions using one column from each
根据说明 here 我创建了两个函数,它们使用 EXECUTE FORMAT
和 return 与 (int,smallint)
相同的 table。
示例定义:
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)
两个函数 return 行数完全相同。示例结果( 将始终按 dist 排序):
(49,0)
(206022,3)
(206041,3)
(92233,4)
有没有办法比较相同行的两个函数之间第二个字段的值,以确保两个结果相同:
例如:
SELECT
function1('tblp1','tblp2',49),function2('tblp1_v2','tblp2_v2',49)
Returns 类似于:
(49,0) (49,0)
(206022,3) (206022,3)
(206041,3) (206041,3)
(92233,4) (133,4)
虽然我不期待相同的结果(每个函数都是一个 topK 查询,我有任意打破的关系/在第二个函数中进行一些优化以获得更快的性能)我可以确保两个函数 return 正确的结果,如果对于每一行,结果中的第二个数字是相同的。在上面的示例中,我可以确保得到正确的结果,因为:
1st row 0 = 0,
2nd row 3 = 3,
3rd row 3 = 3,
4th row 4 = 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。
不保证从函数中 return 编辑行的顺序。如果您可以从函数中 return row_number()
(下例中的 rn
),则:
select
count(f1.dist is null or f2.dist is null or null) as diff_count
from
function1('tblp1','tblp2',49) f1
inner join
function2('tblp1_v2','tblp2_v2',49) f2 using(rn)
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!
行类型两边的括号是消除可能的 table 引用的歧义所必需的。 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;
这适用于每个函数的相同行数以及不同的数字(这将被视为不匹配)。
相关:
- PostgreSQL unnest() with element number
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中的任何地方使用。
供日后参考:
检查行数差异:
SELECT
ABS(count(f1a.*)-count(f2a.*))
FROM
(SELECT f1.dist, row_number() OVER(ORDER BY f1.dist) rn
FROM
function1('tblp1','tblp2',49) f1)
f1a FULL JOIN
(SELECT f2.dist, row_number() OVER(ORDER BY f2.dist) rn
FROM
function2('tblp1_v2','tblp2_v2',49) f2) f2a
USING (rn);
检查相同排序行的 dist 差异:
SELECT
COUNT(*)
FROM
(SELECT f1.dist, row_number() OVER(ORDER BY f1.dist) rn
FROM
function1('tblp1','tblp2',49) f1)
f1a
(SELECT f2.dist, row_number() OVER(ORDER BY f2.dist) rn
FROM
function2('tblp1_v2','tblp2_v2',49) f2) f2a
WHERE f1a.rn=f2a.rn
AND f1a.distance <> f2a.distance;
一个简单的 OVER() 也可能有效,因为函数的结果已经排序但被添加以进行额外检查。
根据说明 here 我创建了两个函数,它们使用 EXECUTE FORMAT
和 return 与 (int,smallint)
相同的 table。
示例定义:
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)
两个函数 return 行数完全相同。示例结果( 将始终按 dist 排序):
(49,0)
(206022,3)
(206041,3)
(92233,4)
有没有办法比较相同行的两个函数之间第二个字段的值,以确保两个结果相同:
例如:
SELECT
function1('tblp1','tblp2',49),function2('tblp1_v2','tblp2_v2',49)
Returns 类似于:
(49,0) (49,0)
(206022,3) (206022,3)
(206041,3) (206041,3)
(92233,4) (133,4)
虽然我不期待相同的结果(每个函数都是一个 topK 查询,我有任意打破的关系/在第二个函数中进行一些优化以获得更快的性能)我可以确保两个函数 return 正确的结果,如果对于每一行,结果中的第二个数字是相同的。在上面的示例中,我可以确保得到正确的结果,因为:
1st row 0 = 0,
2nd row 3 = 3,
3rd row 3 = 3,
4th row 4 = 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。
不保证从函数中 return 编辑行的顺序。如果您可以从函数中 return row_number()
(下例中的 rn
),则:
select
count(f1.dist is null or f2.dist is null or null) as diff_count
from
function1('tblp1','tblp2',49) f1
inner join
function2('tblp1_v2','tblp2_v2',49) f2 using(rn)
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!
行类型两边的括号是消除可能的 table 引用的歧义所必需的。 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;
这适用于每个函数的相同行数以及不同的数字(这将被视为不匹配)。
相关:
- PostgreSQL unnest() with element number
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中的任何地方使用。
供日后参考:
检查行数差异:
SELECT
ABS(count(f1a.*)-count(f2a.*))
FROM
(SELECT f1.dist, row_number() OVER(ORDER BY f1.dist) rn
FROM
function1('tblp1','tblp2',49) f1)
f1a FULL JOIN
(SELECT f2.dist, row_number() OVER(ORDER BY f2.dist) rn
FROM
function2('tblp1_v2','tblp2_v2',49) f2) f2a
USING (rn);
检查相同排序行的 dist 差异:
SELECT
COUNT(*)
FROM
(SELECT f1.dist, row_number() OVER(ORDER BY f1.dist) rn
FROM
function1('tblp1','tblp2',49) f1)
f1a
(SELECT f2.dist, row_number() OVER(ORDER BY f2.dist) rn
FROM
function2('tblp1_v2','tblp2_v2',49) f2) f2a
WHERE f1a.rn=f2a.rn
AND f1a.distance <> f2a.distance;
一个简单的 OVER() 也可能有效,因为函数的结果已经排序但被添加以进行额外检查。