복붙노트

[SQL] 쉼표는 MySQL의 "IN"절에 값을 분리

SQL

쉼표는 MySQL의 "IN"절에 값을 분리

내가 쉼표로 구분하여 여러 ID를 저장하는 곳 내 테이블 중 하나의 열이 있습니다. 내가 쿼리의 "IN"절에이 칼럼의 값을 사용할 수있는 방법이 있나요.

열 (도시) 6,7,8,16,21,2 같은 값을가집니다

나는로 사용할 필요가

select * from table where e_ID in (Select city from locations where e_Id=?)

나는 Crozin의 대답에 만족하고 있어요,하지만 난 제안, 의견 및 옵션에 열려입니다.

귀하의 의견을 공유하시기 바랍니다.

해결법

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

    1.하위 쿼리를 실행하지 않아도 @Jeremy 스미스에서 FIND_IN_SET ()의 예제에, 당신은 가입으로 그것을 할 수 있습니다.

    하위 쿼리를 실행하지 않아도 @Jeremy 스미스에서 FIND_IN_SET ()의 예제에, 당신은 가입으로 그것을 할 수 있습니다.

    SELECT * FROM table t
    JOIN locations l ON FIND_IN_SET(t.e_ID, l.city) > 0
    WHERE l.e_ID = ?
    

    이것은 그 테이블 검사를 수행해야하기 때문에 테이블의 행 위치의 모든 조합에 대한 FIND_IN_SET () 함수를 평가하고, 아주 제대로 수행하는 것으로 알려져있다. 이 인덱스를 사용하지 수 있으며, 그것을 개선 할 수있는 방법이 없습니다.

    난 당신이 나쁜 데이터베이스 설계의 최고를 만들려고 노력하고 있지만이가 얼마나 크게 나쁜 이해해야합니다 말했다 알고있다.

    설명 : 내가 먼저 누구의 전화 번호부에있는 모든 사람을 찾아 볼 것을 요청했다 가정, 중간 또는 초기 마지막으로 "J."입니다 어쨌든 모든 단일 페이지를 스캔해야하기 때문에 책의 정렬 된 순서가,이 경우에 도움이 방법은 없습니다.

    @fthiella에 의해 주어진 LIKE 솔루션은 성능에 관련하여 비슷한 문제가있다. 그것은 인덱싱 할 수 없습니다.

    또한 정말 데이터베이스 컬럼 나쁜에 구분 된 목록을 저장하는 내 대답을 참조? 비정규 화 된 데이터를 저장하는 방법이 다른 함정 대한.

    당신이 인덱스를 저장하는 보조 테이블을 만들 수 있다면, 당신은 도시 목록의 각 항목에 대한 위치를 매핑 할 수 있습니다 :

    CREATE TABLE location2city (
     location INT,
     city INT,
     PRIMARY KEY (location, city)
    ); 
    

    당신은 (단지 표에 언급되지 않음)는 비 효율성을 매핑을 생성 한 시간을 견딜 수있는 모든 가능한 도시에 대한 조회 테이블을 가지고 가정 :

    INSERT INTO location2city (location, city)
      SELECT l.e_ID, c.e_ID FROM cities c JOIN locations l
      ON FIND_IN_SET(c.e_ID, l.city) > 0;
    

    지금 당신은 당신의 테이블의 항목을 찾기 위해 훨씬 더 효율적인 쿼리를 실행할 수 있습니다 :

    SELECT * FROM location2city l
    JOIN table t ON t.e_ID = l.city
    WHERE l.e_ID = ?;
    

    이 인덱스를 사용할 수있다. 이제 당신은 또한 location2city에 대응하는 매핑 행을 삽입 모든 INSERT / UPDATE가 / 위치의 행 삭제하는 것이 알아서해야합니다.

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

    2.여러 ID를 저장하지 않는 뷰의 MySQL의의 관점에서 쉼표 (,)로 구분 - 당신이 "안녕하세요"또는 동일한 meaing있는 텍스트 값을 저장하고 "나는 케이크 등이!" - 즉, 그것은 어떤 meaing이 없습니다.

    여러 ID를 저장하지 않는 뷰의 MySQL의의 관점에서 쉼표 (,)로 구분 - 당신이 "안녕하세요"또는 동일한 meaing있는 텍스트 값을 저장하고 "나는 케이크 등이!" - 즉, 그것은 어떤 meaing이 없습니다.

    당신이해야 할 일은 함께 데이터베이스에서 두 개체를 연결하는 분리 된 테이블을 만드는 것입니다. 다 대다 또는 일대는 SQL 기반 데이터베이스의 관계 (요구 사항에 따라)에 대해 자세히 알아보십시오.

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

    3.오히려 쿼리를 사용 FIND_IN_SET (문서)에 사용보다 :

    오히려 쿼리를 사용 FIND_IN_SET (문서)에 사용보다 :

    SELECT * FROM table 
    WHERE 0 < FIND_IN_SET(e_ID, (
                 SELECT city FROM locations WHERE e_ID=?))
    

    첫 번째 양식 정상화에 대한 일반적인주의 사항 (데이터베이스가 하나의 열에서 여러 값을 저장 안)를 적용하지만, 그것으로 당신이있는 거 붙어 있다면, 위의 문장은 도움이 될 것입니다.

  4. ==============================

    4.이 절에서는 사용하지 않지만, 당신이 무엇을해야합니다 :

    이 절에서는 사용하지 않지만, 당신이 무엇을해야합니다 :

    Select *
    from table
    where
      CONCAT(',', (Select city from locations where e_Id=?), ',')
      LIKE
      CONCAT('%,', e_ID, ',%')
    

    하지만 당신은 E_ID 어떤 쉼표 또는 유쾌한 문자를 포함하지 않도록해야합니다.

    EG

    CONCAT(',', '6,7,8,16,21,2', ',') returns ',6,7,8,16,21,2,'
    
    e_ID=1  --> ',6,7,8,16,21,2,' LIKE '%,1,%'  ? FALSE
    e_ID=6  --> ',6,7,8,16,21,2,' LIKE '%,6,%'  ? TRUE
    e_ID=21 --> ',6,7,8,16,21,2,' LIKE '%,21,%' ? TRUE
    e_ID=2  --> ',6,7,8,16,21,2,' LIKE '%,2,%'  ? TRUE
    e_ID=3  --> ',6,7,8,16,21,2,' LIKE '%,3,%'  ? FALSE
    etc.
    
  5. ==============================

    5.오라클 ..here 문자열 연결에 대한이 하나 wm_concat에 의해 이루어집니다

    오라클 ..here 문자열 연결에 대한이 하나 wm_concat에 의해 이루어집니다

    select * from table where e_ID in (Select wm_concat(city) from locations where e_Id=?)
    

    그래, 난이 조항 "의"우리가 그 일을 할 코드 하나 아래 행에 해당 열을 내리는 데 필요한 넣어 위해 .. raheel 중산에 동의합니다.

    select * from table  where to_char(e_ID) 
    in (
      select substr(city,instr(city,',',1,rownum)+1,instr(city,',',1,rownum+1)-instr(city,',',1,rownum)-1) from 
      (
      select ','||WM_CONCAT(city)||',' city,length(WM_CONCAT(city))-length(replace(WM_CONCAT(city),','))+1 CNT from locations where e_Id=? ) TST 
      ,ALL_OBJECTS OBJ where TST.CNT>=rownum
        ) ;
    
  6. ==============================

    6.당신은 사용해야합니다

    당신은 사용해야합니다

    FIND_IN_SET은 쉼표로 구분 된 값의 스트링 값의 위치를 ​​반환

    mysql> SELECT FIND_IN_SET('b','a,b,c,d');
        -> 2
    
  7. ==============================

    7.이것은 당신이 달성하고 싶은 경우 모르겠어요. MySQL과 CONCATENATE 값에 기능은 그룹 GROUP_CONCAT에서가

    이것은 당신이 달성하고 싶은 경우 모르겠어요. MySQL과 CONCATENATE 값에 기능은 그룹 GROUP_CONCAT에서가

    당신이 뭔가를 시도 할 수 있습니다 :

    select * from table where e_ID in (Select GROUP_CONCAT(city SEPARATOR ',') from locations where e_Id=?)
    
  8. ==============================

    8.당신은 "SPLIT"도시 열 값이 필요합니다. 그것은 같은 것입니다 :

    당신은 "SPLIT"도시 열 값이 필요합니다. 그것은 같은 것입니다 :

    SELECT *
      FROM table
     WHERE e_ID IN (SELECT TO_NUMBER(
                                     SPLIT_STR(city /*string*/
                                               , ',' /*delimiter*/
                                               , 1 /*start_position*/
                                               )
                                     )
                      FROM locations);
    

    현재 MySQL의 split_str 기능에 대한 자세한 내용을보실 수 있습니다 : http://blog.fedecarg.com/2009/02/22/mysql-split-string-function/

    또한, 나는 여기에 오라클의 TO_NUMBER 함수를 사용했다. 적절한 MySQL의 기능을 교체하십시오.

  9. ==============================

    9.IN은 당신이 원하는 것을하지 않을 것이다 검색 쉼표로 분리 된 열을 복용 있도록 행이 필요하지만이 같은 데이터를 제공하는 경우 ( '1', '2', '3')이 작동하지만 수 없습니다 당신의 분야에서이 같은 데이터를 저장합니다 당신이 컬럼에 삽입 무엇이든 그것은 문자열로 전체를 취할 것입니다.

    IN은 당신이 원하는 것을하지 않을 것이다 검색 쉼표로 분리 된 열을 복용 있도록 행이 필요하지만이 같은 데이터를 제공하는 경우 ( '1', '2', '3')이 작동하지만 수 없습니다 당신의 분야에서이 같은 데이터를 저장합니다 당신이 컬럼에 삽입 무엇이든 그것은 문자열로 전체를 취할 것입니다.

  10. ==============================

    10.이 같은 동적으로 준비된 문을 만들 수 있습니다

    이 같은 동적으로 준비된 문을 만들 수 있습니다

    set @sql = concat('select * from city where city_id in (',
                      (select cities from location where location_id = 3),
                      ')');
    prepare in_stmt from @sql;
    execute in_stmt;
    deallocate prepare in_stmt;
    
  11. ==============================

    11.참조 : MySQL은 사용 IN의 쉼표로 구분 된 문자열 ()

    참조 : MySQL은 사용 IN의 쉼표로 구분 된 문자열 ()

    select * from table_name t where (select (CONCAT(',',(Select city from locations l where l.e_Id=?),',')) as city_string) LIKE CONCAT('%,',t.e_ID,',%');
    
    select * from table_name t where ',6,7,8,16,21,2,' LIKE '%,2,%';
    
  12. from https://stackoverflow.com/questions/10480568/comma-separated-values-in-mysql-in-clause by cc-by-sa and MIT license