2014-05-12 2 views
-2

IN()을 사용하는 방법 연산자가 작동하지 않습니다.MySQL IN() 연산자가 작동하지 않습니다.

이 테이블은 예제이며 내가 가진 실제 데이터베이스와 같습니다.

나는 테이블을 추가하거나 변경 허용하지 않는 사람들은 테이블은 다음과 같습니다

students 
+------+------+ 
| id | name | 
+------+------+ 
| 1 | ali | 
| 2 | man | 
| 3 | sos | 
+------+------+ 

Classes 
+------+---------+ 
| c_id | students| 
+------+---------+ 
| 1 | 1,2,3,4 | 
| 2 | 88,33,55| 
| 3 | 45,23,72| 
+------+---------+ 

내가이 쿼리를 사용하는 경우는 ID = 1 때문에 "ID로 나에게 단지 학생을 반환 IN (students) "첫 번째 값이 같으면 1을 반환합니다.

select name,c_id from students,classes where id IN (students); 

내가 PHP를 추가하는 것보다 목록을 가져올 때. 그것은 잘 동작합니다. 그러나이 솔루션은 루프가 필요하며 많은 쿼리 비용이 듭니다.

select name,c_id from students,classes where id IN (1,2,3,4); 

FIND_IN_SET()

같은 일이, 그것은 단지 하나를 반환 할 것하지만, 다른 위치에있는 값 경우 당신은 세 개의 테이블이 필요 0

+0

@Strawberry는 -_- 방법 Yessssssss를 만들기 위해? – alnassre

+2

정규화를 참조하십시오. 까다로운 개념이지만, 내가 그립을 잡을 수 있다면 누구나 할 수 있습니다. – Strawberry

답변

3

IN 연산자는 올바르게 작동합니다.

먼저 데이터를 표준화하도록 구조 조정하고 값을 쉼표로 구분 된 목록으로 저장하지 마십시오.

둘째, 쉼표로 구분 된 값 목록을 포함하는 열을 처리해야하는 경우 MySQL은 FIND_IN_SET() 함수를 제공합니다.


후속

도랑 조인 작업에 대한 구식 쉼표 구문 대신 JOIN 키워드를 사용합니다. 그리고 WHERE 절의 Join 술어를 ON 절로 재배치하십시오. 열 참조를 완전히 한정하십시오 (예 :A는 열에서 "콤마 분리 된리스트"기억 한번 강조

SELECT s.name 
    , c.c_id 
    FROM students s 
    JOIN classes c 
    ON FIND_IN_SET(s.student_id,c.students) 
ORDER BY s.name, c.c_id 

안티 패턴이고; 관계형 이론과 정규화에 반대하며 관계형 데이터베이스에 대한 모범 사례는 무시합니다. O

향상된 성능을 주장 할 수도 있지만이 패턴은 성능을 향상시키지 않습니다. 오히려 쿼리 및 DML 작업에 불필요한 복잡성을 추가합니다.

+0

첫 번째 ID가 1을 반환 할 때 FIND_IN_SET()과 같은 것을 사용했다. 예 : FIND_IN_SET (' 1 ','1,2,3 ') 그러나 2 또는 3에 대해서는 0입니다. – alnassre

+1

'SELECT FIND_IN_SET ('2 ','1,2,3 ')'는' 2 '가 아니라'0 '이 아닌 몇 가지 권장 사항 : 조인 작업을 위해 구식 쉼표 구문을 버리고 e'JOIN' 키워드를 사용하십시오. 조인 술어를 ON 절로 재배치하십시오. 또한 멀티 테이블 쿼리에서 모든 열 참조를 완전하게 한정합니다. – spencer7593

+0

왼쪽 조인을 사용하는 FIND_IN_SET()이 제대로 작동했습니다. 데이터베이스에 쉼표 뒤에 공백이 있습니다. FIND_IN_SET() 공백을 제거한 후 완벽하게 작동합니다. 감사 – alnassre

2

돌아갑니다. 한 테이블 students, 하나 개의 테이블 classes 다음 하나 개의 테이블, 말, 등등

c_id | student_id 
1 | 1 
1 | 2 
1 | 3 
1 | 4 
2 | 88 

과 같은 students_to_classes 포함 뭔가. 이에 대한 배경에 대해 "m 관계 N" 은 그럼 당신은

select c_id from students_to_classes where student_id in (1,2,3,4) 

구글을 조회 할 수 있습니다.

편집

내가 특별히 다른 테이블 구조를 요청하지 않을 알고 있지만,이 IN 작동하는 데이터 유형 (단일 번호)를 갖는 방법이다. 이것이 올바른 방법이라는 것을 믿어주세요. IN과 같은 단순한 문제에 부딪히는 이유는 비표준 방식을 사용하고 있다는 것입니다. 표준 방식의 문제는 일반적으로 좋지 않습니다. 생각.

+0

그래, 잘 넣어. 나는 그가 세 개의 테이블을 가지면 원래 다음과 같은 쿼리를 요청했다 : SELECT 이름, 학생의 c_id 내부 조인 students_to_classes stc on s.student_id = stc.student_id; (내 생각에) –

+0

@ ers81239 당신 말이 맞습니다.지도 테이블에 대해 묻는 것이 아닙니다. 테이블은 단지 예일뿐입니다. 주된 질문은 그것을 사용할 때 IN()이 다른 결과를 반환한다는 것입니다. – alnassre

+0

@alnassre 당신이 이것을 요구하지 않는다는 것을 이해한다, 그러나 그것은 어쨌든 대답이다.) – Nicolas78

0

그렇다면 IN 기능이 작동하는 방식이 아닙니다. 대신

: 사용

WHERE id=1 or id=2 or id=3 or id=4 

:

WHERE id IN (1,2,3,4) 

이 어쨌든, 당신의 논리가 정확하지 않은 당신이 같이 가능한 일치 항목의 목록을 때에 사용. 학급과 학생의 관계는 다 대다이므로 세 번째 테이블이 필요합니다. 각 클래스의 학생들을 저장할 수있는 studend_class라고합시다.

student 
+------+------+ 
| id | name | 
+------+------+ 
| 1 | ali | 
| 2 | man | 
| 3 | sos | 
+------+------+ 

class 
+------+---------+ 
| id | name | 
+------+---------+ 
| 1 | math | 
| 2 | english | 
| 3 | science | 
+------+---------+ 

student_class 
+------------+-------------+ 
| class_id | student_id | 
+------------+-------------+ 
|   1 |   1 | 
|   1 |   2 | 
|   1 |   3 | 
|   3 |   3 | 
+--------------+-----------+ 

위의 예에서 모든 학생들은 수학 수업에 참여하고 있으며 알리 역시 과학 수업에 참여하고 있습니다. 당신은 무엇 클래스에있는 학생들이 알고 whant 경우

마지막으로,의 수학을 가정 해 봅시다, 당신은 사용할 수 있습니다

SELECT s.id, s.name, c.name 
FROM student s 
INNER JOIN student_class sc ON sc.student_id=s.id 
INNER JOIN class c ON sc.class_id = c.id 
WHERE c.name="math"; 
관련 문제