2017-11-25 142 views
1

有没有办法在普通PL/pgSQL中匹配实体? 比方说,我想通过使用比较三个单属性的文本搜索查询来识别匹配搜索一个人在客户表:通过属性匹配两个表的行

SELECT id, first_name, last_name, birthdate 
    FROM customers_index 
    WHERE first_name @@ plainto_tsquery('simple','John') 
     AND last_name @@ plainto_tsquery('simple','Smith') 
     AND birthdate = '17.08.1967'; 

但这样做对每个人是有点乏味,因为我有一整张我想要以这种方式匹配的人。在任何“正常编程语言”的帮助下,我现在循环一个数组,直到我发现每一行的现有匹配成为一个新表,但有没有办法在普通的PL/pgSQL中执行此操作?

回答

1

我想在PL/PGSQL与阵列相结合作为输入参数,将很好地工作的功能(类似于Oracle的PL/SQL):

CREATE OR REPLACE FUNCTION customers(first_names text[], last_names text[], 
    birthdays date[]) 
    RETURNS SETOF customers_index as 
$BODY$ 
DECLARE 
    i integer; 
    elements integer; 
    rw customers_index%rowtype; 
BEGIN 

    elements := array_length (first_names); 

    for i in 1..elements loop 

    for rw in SELECT ci.* 
     FROM customers_index ci 
     WHERE ci.first_name @@ plainto_tsquery('simple', first_names[i]) 
     AND ci.last_name @@ plainto_tsquery('simple', last_names[i]) 
     AND ci.birthdate = birthdays[i] 
    loop 
     return next rw; 
    end loop; 
    end loop; 

    return; 

END; 
$BODY$ 
    LANGUAGE plpgsql VOLATILE 
    COST 100; 

和实施将是这个样子:

select 
    id, first_name, last_name, birthdate 
from 
    customers(array['John', 'Jane'], array['Smith', 'Doe'], 
     array ['17.08.1967', '16.07.1970']) 

如果当然,假设你的数据来自其他地方,实际的实现应该看起来更清洁。

另外,我不保证这是超高效的,但它是从A到B的快速路径,并且有一些GIN索引,或者至少是生日的索引,它可能实际上运行得很漂亮很好。

+0

谢谢,我可以根据您的建议创建一个工作解决方案。只是一个小问题:array_length()需要两个参数,所以array_length(first_names,1)做了这个工作。由于没有人提供解决方案,我会将您的解决方案标记为最佳答案。 – MayaK