Sql 使用每个表函数中的一列比较两个表函数的结果

Sql 使用每个表函数中的一列比较两个表函数的结果,sql,postgresql,postgresql-9.3,set-returning-functions,Sql,Postgresql,Postgresql 9.3,Set Returning Functions,根据指令,我创建了两个函数,它们使用EXECUTE格式并返回相同的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 _tb

根据指令,我创建了两个函数,它们使用EXECUTE格式并返回相同的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)
这两个函数返回的行数完全相同。样本结果将始终按地区排序:

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

例如:

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)
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;
虽然我不希望得到相同的结果,但每个函数都是topK查询,并且我的关系被任意打破/第二个函数中进行了一些优化以提高性能,如果结果中的每一行第二个数字相同,我可以确保这两个函数返回正确的结果。在上面的示例中,我可以确保得到正确的结果,因为:

1st row 0 = 0,
2nd row 3 = 3,
3rd row 3 = 3,
4th row 4 = 4
尽管第四排是92233=133

是否有方法仅获取每个函数结果的第二个字段,以批量比较它们,例如,与以下内容进行比较:

(49,0)      (49,0)
(206022,3)  (206022,3)
(206041,3)  (206041,3)
(92233,4)   (133,4)
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。

不能保证从函数返回行的顺序。如果您可以从函数返回以下示例中的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)
是否有办法只获取每个函数结果的第二个字段,以批量比较它们

以下所有答案都假设行是按匹配顺序返回的

博士后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!
这适用于每个函数中相同数量的行以及不同数量的行,这将被视为不匹配

相关的:

逐行连接集合 相关答复:

旁白: 执行格式不是一套plpgsql功能。返回查询为。是构建查询字符串的方便函数,可在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);
检查相同有序行的距离差异:

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也可以使用,因为函数的结果已经排序,但是添加了额外的检查。

您确定它适用于PostgreSQL 9.3吗?我得到一个语法错误,我只在上见过它。@Alexandros它是9.4+feature@Alexandros据我所知,即使它在9.3中工作,它对结果集的编号也可能与函数内部的顺序不同,因此必须在函数内部指定行号。@Alexandros:是的,对不起,带序数是9.4页,而不是9.3页。我又添加了一些。@ClodoaldoNeto:具有序号的行,就像它们是从函数返回的一样。因此,是的,如果返回的行顺序不匹配,我认为没有办法解决这个问题,我们需要在每个函数中添加行号并返回它们……您必须使用select*from function 1'tblp1'、'tblp2',49来设置返回函数。不要将它们放入选择列表。您添加的内容将始终按dist排序。您确定,这不会导致误报吗?@ErwinBrandstetter这是一个按dist LIMIT k排序的topK查询,因此函数内的结果按dist排序。我想在具体示例中检查,我得到的答案是dist=1,两个答案的dist=3,一个答案的dist=4表示k=4。这两个函数在不同的表上运行第二个函数在优化的表上运行,我想确保这两个函数为所有k个结果返回相同的dist。在我们的例子中,dist 1和dist 3的结果总是相同的,没有dist=3的其他结果,但是在dist=4的情况下,我可能会得到dist=4的许多结果。那么,行是按匹配的顺序返回的吗?剩下的对这个问题并不重要。@a_horse_和_no_name:这实际上没有抓住问题的重点。
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;