所以我从Python网络服务器获得了一个数组codes
,我需要选择所有具有与这些codes
中的任何一列匹配的列的行:
SELECT a.*
FROM a
LEFT JOIN b ON b.code = a.bcode
WHERE b.code = ANY(codes);
但问题是,这些代码可能只是部分代码,只是代码的开头。因此,虽然完整代码总是长5个字母(它们存储为字符串),但我收到的代码数组可能类似于['01', '4332', '34443']
。如果b
中的行有'01233'
作为列的值,则它应该与数组中的'01'
匹配。请注意,它与'23'
不匹配,只应与开头匹配。
基本上我想要这样的东西:
SELECT a.*
FROM a
LEFT JOIN b ON b.code = a.bcode
WHERE b.code LIKE ANY(codes || '%');
显然附加到像codes || '%'
这样的数组是不合法的,所以我怎么能这样做?
答案 0 :(得分:2)
可能有更好的方法来做到这一点。但是一般概念对我来说是有意义的:如果项目的长度小于5,则更改数组以追加%
字符。
SELECT [...]
FROM [...] x
WHERE x.code LIKE ANY(ARRAY(
SELECT CASE WHEN LENGTH(u) < 5 THEN u || '%' ELSE u END
FROM UNNEST([your array]) u)
);
工作示例:
SELECT g
FROM generate_series(9995, 10005) g
WHERE g::TEXT LIKE ANY(ARRAY(
SELECT CASE WHEN LENGTH(u) < 5 THEN u || '%' ELSE u END
FROM UNNEST(ARRAY['999','10005']) u)
);
结果:
9995
9996
9997
9998
9999
10005
答案 1 :(得分:1)
您需要弄清楚如何将数组传递给查询。显然,您可以在Python中构造一个WHERE
子句,并执行以下操作:
where code like '01%', or
code like '4332%' or
code like '34443%'
您可以将其缩短为正则表达式:
where code ~ '^(01|4332|34443)'
或者,您可以将其作为Postgres数组传递,执行以下操作:
select v.*, p2.pat
from (values ('a'), ('abc'), ('abcd'), ('bacd')) v(x) cross join
(select array['a', 'b'] as pat) p, lateral
unnest(p.pat) p2(pat)
where v.x like p2.pat || '%';
如果要返回匹配的模式,使用Postgres数组特别有用。
答案 2 :(得分:1)
这个小功能可以完成这项工作:
create or replace function array_for_like(text[])
returns text[] language sql as $$
select string_to_array(concat(array_to_string($1, '%,'), '%'), ',')
$$;
示例:
with my_table(code) as (
values
('10001'),
('10002'),
('20001'),
('20002'),
('30001')
)
select *
from my_table
where code like any(array_for_like(array['10', '30']))
code
-------
10001
10002
30001
(3 rows)