2017-02-12 6 views
0

postgresql (9.6)에서 'alice chaplin'또는 'alice'또는 'alice chaplin meyer'유형의 가변 길이 사용자 입력이 주어지면, 뿐만 아니라 'lic chapl', 나는 firstname 또는 성 lastname에 'alice'가 포함 된 레코드를 검색하고 싶습니다. 그리고 firstname 또는 lastname에는 'chaplin'을 포함하고 firstname 또는 lastname에는 'meyer'를 포함합니다.Postgres : 사용자 입력의 모든 단어에 LIKE를 사용하고 결과를 AND- 처리하는 방법

나는 일치에 대한 ILIKE %searchterm%을 사용하기로 결정했다, 그래서 쿼리는 아마의 라인을 따라 다음과 같습니다 시도의 많은 및 검색, noth 후

... where 
    ((lastname ILIKE '%' || SEARCHTERM1 || '%') OR (firstname ILIKE '%' || SEARCHTERM1 || '%')) 
AND ((lastname ILIKE '%' || SEARCHTERM2 || '%') OR (firstname ILIKE '%' || SEARCHTERM2 || '%')) 
AND etc. 

ing은 이것을 해결합니다. 최후의 수단으로 분할 검색 문자열을 반복하면서 매우 복잡한 프로 시저 pgplsql 함수를 작성하여 ILIKE 결과를 교차시키지 만 그러한 실행을 해결하는 좀 더 관용적 인 SQL 방식이 있어야합니다 문제의

답변

1

string_to_array을 사용하면 입력 문자열을 단어 배열로 변환 할 수 있습니다. 그런 다음 unnest을 사용하여 배열을 (가상) 테이블로 변환하고 단어를 조작하여 앞뒤에 '%'를 추가 할 수 있습니다. 마지막으로 ILIKE ALL (SELECT ...)을 사용하여 ALL 비교를 사용할 수 있습니다. 이 ALL은 실제로 원하는대로 결과를 AND 처리합니다.

WITH q AS 
(
    SELECT 'Alice Chaplin Meyer'::text AS q 
) 
, words AS 
(
SELECT 
    '%' || word || '%' AS wordish 
FROM 
    q 
    JOIN LATERAL unnest(string_to_array(q, ' ')) AS a(word) ON true 
) 
SELECT 
    * 
FROM 
    t 
WHERE 
    concat_ws(' ', first_name, last_name) ILIKE ALL(SELECT wordish FROM words) 

당신은 http://rextester.com/LNB38296

참고 문헌에서 모두 확인할 수 있습니다

  • Using ALL
  • 참고

    1. string_to_array and unnest
    2. : 이것은 아마 간단하게 할 수 있지만, 내가 선호 한 단계별 접근법.

    +0

    고마워요.하지만 같은 질문을합니다. 첫 번째 검색 문자열 (또는 해당 검색 문자열을 분할하여 생성 된 배열)에서 올바른 양의 AND 절로 이동하는 방법입니다. 예. AND 절의 내용은 문제가되지 않습니다. 위에서 설명한 내용도 작동합니다. 문제는 검색 문자열에서 AND로, 즉 개별 결과의 교차를 얻는 방법입니다. – kmptkp

    +0

    나는 실제 질문을하지 않았다 ... 미안. – joanolo

    +0

    훌륭해, 고마워! 당신의 조인은 불필요합니다. 그 줄은 다음과 같이 단순화 될 수 있습니다 :'FROM q, unnest (string_to_array (q, '')) AS word)'(간단히하기 위해 질문을 인라인으로 편집 할 충분한 점수가 없다고 생각합니다.) {위의 의견에 대한 향후 독자의주의 사항 : 그들은 @ joanolo의 대답의 이전 버전에 관한 내용이며 이는 완전히 다릅니다.} – kmptkp