복붙노트

[SQL] 그것은 특정 값에 대해 열을 쉼표로 구분을 조회 할 수 있습니까?

SQL

그것은 특정 값에 대해 열을 쉼표로 구분을 조회 할 수 있습니까?

나는이 (내가 변경할 수 있도록 소유하지 않은)이 유사한 레이아웃 테이블을.

ID | CATEGORIES
---------------
1  | c1
2  | c2,c3
3  | c3,c2
4  | c3
5  | c4,c8,c5,c100

나는 특정 카테고리 ID를 포함하는 행을 반환해야합니다. 값이 문자열의 어느 곳이 될 수 있기 때문에 나는, LIKE 문으로 쿼리를 작성하여 시작

테이블 ID SELECT WHERE 카테고리 '% C2 %'등; 반환 행 2와 3

테이블 ID SELECT WHERE 카테고리 LIKE '% C3 % "와 같은 카테고리'% C2 % '; 다시 행 2, 3 저에게 있지만 4 행시겠습니까

카테고리 같은 테이블 SELECT ID '% C3 %'또는 카테고리 '% C2 %'등; 다시 행 2, 3 저에게, 4시겠습니까

나는 모든 LIKE 문을 좋아하지 않는다. 나는 오라클 설명서 FIND_IN_SET ()를 발견했습니다하지만 10g에서 작동하지 않습니다. 나는 다음과 같은 오류가 발생합니다 :

ORA-00904: "FIND_IN_SET": invalid identifier
00904. 00000 -  "%s: invalid identifier"

이 쿼리를 실행할 때 : 테이블에서 SELECT ID를 WHERE FIND_IN_SET ( 'C2', 카테고리); (예를 들어 워드 프로세서) 또는이 조회 표 SELECT FROM WHERE FIND_IN_SET ID ( 'C2'카테고리) <> 0; (구글에서 예)

나는 그것이 행 2와 3을 반환 할 것으로 예상합니다.

이러한 쿼리를 작성하는 대신 LIKE 문의 톤을 사용하는 더 좋은 방법이 있나요?

해결법

  1. ==============================

    1.당신은 등을 사용 할 수 있습니다. 당신은 당신의 검색에서 쉼표를 포함해야합니다, 그래서 부분 값과 일치하지 않습니다. 그것은 또한 당신이 시작 또는 텍스트의 끝에서 값을 검색하기 위해 여분의 쉼표를 제공해야합니다 것을 의미한다 :

    당신은 등을 사용 할 수 있습니다. 당신은 당신의 검색에서 쉼표를 포함해야합니다, 그래서 부분 값과 일치하지 않습니다. 그것은 또한 당신이 시작 또는 텍스트의 끝에서 값을 검색하기 위해 여분의 쉼표를 제공해야합니다 것을 의미한다 :

    select 
      * 
    from
      YourTable 
    where 
      ',' || CommaSeparatedValueColumn || ',' LIKE '%,SearchValue,%'
    

    모든 쿼리가 특히 선도적 인 와일드 카드, 등을 사용하지만이 쿼리는 느려집니다.

    그리고 항상 위험이있다. 값 주위에 공간이있는 경우, 또는 값 자체가이 경우에 그들은 (CSV 파일처럼) 따옴표로 둘러싸여 쉼표를 포함 할 수 있습니다,이 쿼리하지 않습니다 작업 당신은 당신의 쿼리를 늦추고, 더 많은 로직을 추가해야합니다 더 나아가.

    더 나은 솔루션이 범주에 대한 자식 테이블을 추가하는 것입니다. 또는 오히려조차 가지 범주에 대한 별도의 테이블, 크로스 링크들을 그 YourTable에 테이블.

  2. ==============================

    2.당신은 1 열 테이블을 반환 파이프 라인 테이블 함수를 작성할 수 있습니다. 각 행은 쉼표의 값은 문자열을 분리한다. 이 같은 사용 무언가 목록에서 문자열을 나타 테이블에 행으로 넣어 :

    당신은 1 열 테이블을 반환 파이프 라인 테이블 함수를 작성할 수 있습니다. 각 행은 쉼표의 값은 문자열을 분리한다. 이 같은 사용 무언가 목록에서 문자열을 나타 테이블에 행으로 넣어 :

    PIPE ROW(ltrim(rtrim(substr(l_list, 1, l_idx - 1),' '),' '));
    

    용법:

    SELECT * FROM MyTable 
    WHERE 'c2' IN TABLE(Util_Pkg.split_string(categories));
    

    자세한 내용은 여기를 참조하십시오 : 오라클 문서를

  3. ==============================

    3.아니오 그리고 예 ...

    아니오 그리고 예 ...

    "예":

    표준화 데이터 (권장) - 즉 별도의 각 categorie이되도록 categorie 열을 분할 ... 당신은 단지 일반 faschion에서이를 조회 할 수 있습니다 ...

    "아니": 만큼 당신이 "의사 구조를"계속 거기 몇 가지 문제 (성능 및 기타) 될 것입니다 그리고 당신은에 비슷한해야 할 것 :

    SELECT * FROM MyTable WHERE categories LIKE 'c2,%' OR categories = 'c2' OR categories LIKE '%,c2,%' OR categories LIKE '%,c2'
    

    당신은 절대적으로 당신은 다음과 같은 FIND_IN_SET라는 함수를 정의 할 수 있어야합니다 경우 :

    CREATE OR REPLACE Function FIND_IN_SET
       ( vSET IN varchar2, vToFind IN VARCHAR2 )
       RETURN number
    IS
        rRESULT number;
    BEGIN
    
    rRESULT := -1;
    SELECT COUNT(*) INTO rRESULT FROM DUAL WHERE vSET LIKE ( vToFine || ',%' ) OR vSET = vToFind OR vSET LIKE ('%,' || vToFind || ',%') OR vSET LIKE ('%,' || vToFind);
    
    RETURN rRESULT;
    
    END;
    

    당신은 다음과 같은 해당 기능을 사용할 수 있습니다 :

    SELECT * FROM MyTable WHERE FIND_IN_SET (categories, 'c2' ) > 0;
    
  4. ==============================

    4.미래 수색자 위해, 정규 표현식 방법을 잊지 마세요 :

    미래 수색자 위해, 정규 표현식 방법을 잊지 마세요 :

    with tbl as (
    select 1 ID, 'c1' CATEGORIES from dual
    union
    select 2 ID, 'c2,c3' CATEGORIES from dual
    union
    select 3 ID, 'c3,c2' CATEGORIES from dual
    union
    select 4 ID, 'c3' CATEGORIES from dual
    union
    select 5 ID, 'c4,c8,c5,c100' CATEGORIES from dual
    )
    select * 
    from tbl
    where regexp_like(CATEGORIES, '(^|\W)c3(\W|$)');
    
            ID CATEGORIES
    ---------- -------------
             2 c2,c3
             3 c3,c2
             4 c3
    

    단어 경계에있는이 경기는 쉼표 다음에 공백 그래서 경우에도 그것은 여전히 ​​작동합니다. 당신은 더 엄격하고 콤마 분리형 값은 쉼표로 '\ W'를 대체 할 경우에만 일치합니다. 어쨌든, 정규 표현식과 같이 : 워드 경계 또는 선의 한쪽 끝 그룹이어서 대상 검색 값 다음 라인의 시작 또는 단어 경계 중 어느 하나의 그룹을 일치.

  5. ==============================

    5.만큼 쉼표로 구분 된 목록은 512 자 이하로, 당신은 또한 정기적으로이 경우에 식 (오라클의 정규 표현식 기능, 512 자로 제한됩니다 예를 들어, REGEXP_LIKE을 ())를 사용할 수 있습니다 :

    만큼 쉼표로 구분 된 목록은 512 자 이하로, 당신은 또한 정기적으로이 경우에 식 (오라클의 정규 표현식 기능, 512 자로 제한됩니다 예를 들어, REGEXP_LIKE을 ())를 사용할 수 있습니다 :

    SELECT id, categories
      FROM mytable
     WHERE REGEXP_LIKE('c2', '^(' || REPLACE(categories, ',', '|') || ')$', 'i');
    

    | 위의 나는 정규 표현식 교대 연산자와 쉼표를 대체하고있다. 구분 된 값의 목록이 이미되어있는 경우 |, 훨씬 더 나은 -delimited.

  6. from https://stackoverflow.com/questions/7212282/is-it-possible-to-query-a-comma-separated-column-for-a-specific-value by cc-by-sa and MIT license