加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

Postgres类似于SQL Server中的CROSS应用程序

发布时间:2020-12-12 08:25:28 所属栏目:MsSql教程 来源:网络整理
导读:我需要将针对MS SQL Server 2005编写的SQL查询迁移到Postgres 9.1. 在此查询中替换CROSS APPLY的最佳方法是什么? SELECT *FROM V_CitizenVersions CROSS APPLY dbo.GetCitizenRecModified(Citizen,LastName,FirstName,MiddleName,BirthYear,BirthMonth,Birth
我需要将针对MS SQL Server 2005编写的SQL查询迁移到Postgres 9.1.
在此查询中替换CROSS APPLY的最佳方法是什么?
SELECT *
FROM V_CitizenVersions         
CROSS APPLY     
       dbo.GetCitizenRecModified(Citizen,LastName,FirstName,MiddleName,BirthYear,BirthMonth,BirthDay,..... ) -- lots of params

GetCitizenRecModified()函数是一个表值函数.我不能放置这个函数的代码,因为它真的很大,这使得一些困难的计算,我不能放弃它.

解决方法

在Postgres 9.3或更高版本中使用LATERAL连接:
SELECT v.col_a,v.col_b,f.*  -- no parentheses here,f is a table alias
FROM   v_citizenversions v
LEFT   JOIN LATERAL f_citizen_rec_modified(v.col1,v.col2) f ON true
WHERE  f.col_c = _col_c;

为什么LEFT JOIN LATERAL … ON?

> Record returned from function has columns concatenated

对于较旧的版本,有一个非常简单的方法来完成我认为您正在设置的返回函数(RETURNS TABLE or RETURNS SETOF record OR RETURNS record):

SELECT *,(f_citizen_rec_modified(col1,col2)).*
FROM   v_citizenversions v

该函数为外部查询的每一行计算一次值.如果函数返回多行,则相应的乘积相乘.所有括号在语法上都需要分解行类型.表函数可以看起来像这样:

CREATE OR REPLACE FUNCTION f_citizen_rec_modified(_col1 int,_col2 text)
  RETURNS TABLE(col_c integer,col_d text) AS
$func$
SELECT s.col_c,s.col_d
FROM   some_tbl s
WHERE  s.col_a = $1
AND    s.col_b = $2
$func$LANGUAGE sql;

如果要应用WHERE子句,因为列在同一级别上不可见,则需要将其包装在子查询或CTE中. (而且,无论如何,性能更好,因为您可以防止对函数的每个输出列进行重复评估):

SELECT col_a,col_b,(f_row).*
FROM (
   SELECT col_a,f_citizen_rec_modified(col1,col2) AS f_row
   FROM   v_citizenversions v
   ) x
WHERE (f_row).col_c = _col_c;

还有其他一些方法可以做到这一点或类似的事情.这一切都取决于你想要什么.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读