根据说明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)
两个函数都返回完全相同的行数。样本结果(将始终按dist排序):
(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
尽管第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。
答案 0 :(得分:1)
无法保证从函数返回行的顺序。如果您可以从函数返回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)
答案 1 :(得分:1)
有没有办法只获得每个函数结果的第二个字段,批量比较它们?
以下所有答案均假设行以 匹配 顺序返回。
具有从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.
如果返回的行数不相同(这将完全打破它),则默认为行的笛卡尔乘积。
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中的任何地方使用。
答案 2 :(得分:0)
供将来参考:
检查行数差异:
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()也可能有效,因为函数的结果已经被排序但是被添加以进行额外的检查。