Arrays 其中条件使用循环中数组的信息
我想清理美国的地址数据。每当状态代码出现在前两个子字符串(子字符串(地址,1,2))中时,我想从列(地址)中输入状态代码。我构建了一个foreach循环,循环遍历一系列美国州。但是,条件Arrays 其中条件使用循环中数组的信息,arrays,postgresql,loops,where,plpgsql,Arrays,Postgresql,Loops,Where,Plpgsql,我想清理美国的地址数据。每当状态代码出现在前两个子字符串(子字符串(地址,1,2))中时,我想从列(地址)中输入状态代码。我构建了一个foreach循环,循环遍历一系列美国州。但是,条件where=substring(address,1,2)=field不起作用。field在循环中使用:foreach field in array arr loop 整个代码如下所示: create or replace function imp() RETURNS VOID AS $$ declare fiel
where=substring(address,1,2)=field
不起作用。field
在循环中使用:foreach field in array arr loop
整个代码如下所示:
create or replace function imp() RETURNS VOID AS $$
declare field varchar;
declare arr varchar[] := array['AL ', 'AK ', 'AZ ', 'AR ', 'CA ', 'CO ', 'CT ', 'DE ', 'DC ', 'FL ', 'GA ', 'HI ', 'ID ', 'IL ', 'IN ', 'IA ', 'KS ', 'KY ', 'LA ', 'ME ', 'MD ', 'MA ', 'MI ', 'MN ', 'MS ', 'MO ', 'MT ', 'NE ', 'NV ', 'NH ', 'NJ ', 'NM ', 'NY ', 'NC ', 'ND ', 'OH ', 'OK ', 'OR ', 'PA ', 'RI ', 'SC ', 'SD ', 'TN ', 'TX ', 'UT ', 'VT ', 'VA ', 'WA ', 'WV ', 'WI ', 'WY '];
begin
foreach field in array arr LOOP
update DE_inventor t1 set address_=t2.address_ from (
select
concat(address_, ' ', field)
as address_, pat_no, inventor
from DE_inventor
where ctry_code_inv = 'US' and substring(address, 1, 2)= field
) as t2
where t1.pat_no = t2.pat_no and t1.inventor = t2.inventor;
END LOOP;
RETURN;
END;
$$ language 'plpgsql';
select imp()
;
循环在concat(address_',,field)
中运行良好(在另一个过程中也测试和使用过),但在where条件下不起作用。
有人知道为什么以及可以做什么吗?在我看来,数组元素中的额外空间:
declare arr varchar[] := array['AL ', 'AK ', 'AZ ',
^ ^ ^ those
正在阻止这一切成为现实:
substring(address, 1, 2)= field
子字符串(x,1,2)将始终是两个字符,并且永远不会与数组元素所在的三个字符字段相匹配
那么首先,你能把多余的空间去掉并试试吗
create or replace function imp() RETURNS VOID AS $$
declare
field varchar;
arr varchar[] := array['AL', 'AK', 'AZ', ... 'WY'];
begin
第二,您可以将状态加载到一个表中,并使用该表而不是数组吗?根据你所做的,它可能不止一次派上用场
第三,如果inventor
和pat_no
是表的主键,那么我认为单个update语句可能比函数/循环更好:
update de_inventor
set address_ = address_ || ' ' || left (address, 1, 2)
where
ctry_code_inv = 'US' and
left (address, 2) in ('AL', 'AK', 'AZ', 'AR' .. 'WY')
如果这些不是主键,那么update语句可能会产生意想不到的后果,但我不能确定这一点
这两种方式都值得思考。在我看来,这就像数组元素中的额外空间:
declare arr varchar[] := array['AL ', 'AK ', 'AZ ',
^ ^ ^ those
正在阻止这一切成为现实:
substring(address, 1, 2)= field
子字符串(x,1,2)将始终是两个字符,并且永远不会与数组元素所在的三个字符字段相匹配
那么首先,你能把多余的空间去掉并试试吗
create or replace function imp() RETURNS VOID AS $$
declare
field varchar;
arr varchar[] := array['AL', 'AK', 'AZ', ... 'WY'];
begin
第二,您可以将状态加载到一个表中,并使用该表而不是数组吗?根据你所做的,它可能不止一次派上用场
第三,如果inventor
和pat_no
是表的主键,那么我认为单个update语句可能比函数/循环更好:
update de_inventor
set address_ = address_ || ' ' || left (address, 1, 2)
where
ctry_code_inv = 'US' and
left (address, 2) in ('AL', 'AK', 'AZ', 'AR' .. 'WY')
如果这些不是主键,那么update语句可能会产生意想不到的后果,但我不能确定这一点
这两种方法都值得思考。此更新不需要循环或plpgsql代码,因为简单的SQL语句可以完成以下任务:
update de_inventor
set address_ = concat(address_, ' ', substring(address, 1, 2))
where ctry_code_inv = 'US'
and substring(address, 1, 2) in ('AL', 'AK', 'WY'); -- list of all state codes here
在这种情况下,SQL方法比函数中的循环更有效、更简单。此更新不需要循环或plpgsql代码,因为simple SQL语句可以完成以下任务:
update de_inventor
set address_ = concat(address_, ' ', substring(address, 1, 2))
where ctry_code_inv = 'US'
and substring(address, 1, 2) in ('AL', 'AK', 'WY'); -- list of all state codes here
在这种情况下,SQL方法比函数中的循环更有效、更简单。非常好的建议。是的,我错过了最明显的事情,因为我完全专注于使用循环。非常好的建议。是的,我错过了最明显的事情,因为我完全专注于使用循环。回答很好。非常感谢。是的,确实,我没有注意额外的空间,对不起,但我现在使用第二种方法。使用“left”而不是“substring”有什么好处吗?
left
比substring
唯一可能的好处是代码更少,并且可能对读者更透明,因为您使用的是左两个字符<代码>子字符串是相当主流的,因此任何熟悉SQL或计算的人都应该知道这意味着什么,有人可能会说它比左
更标准。顺便说一下,当我说left(地址,1,2)
时,应该是left(地址,2)
。我很高兴这有帮助。是的,每当您可以通过循环执行单个SQL事务时,您都希望这样做。循环在不需要的时候被广泛使用,所以不要感觉糟糕。很好的答案。非常感谢。是的,确实,我没有注意额外的空间,对不起,但我现在使用第二种方法。使用“left”而不是“substring”有什么好处吗?left
比substring
唯一可能的好处是代码更少,并且可能对读者更透明,因为您使用的是左两个字符<代码>子字符串是相当主流的,因此任何熟悉SQL或计算的人都应该知道这意味着什么,有人可能会说它比左
更标准。顺便说一下,当我说left(地址,1,2)
时,应该是left(地址,2)
。我很高兴这有帮助。是的,每当您可以通过循环执行单个SQL事务时,您都希望这样做。循环在不需要时被广泛使用,所以不要感觉糟糕。