2009-10-25 3 views
0

아래와 같은 쿼리를 사용하면 ID의 색상이 파란색, 보라색, 녹색, 흰색 및 검은 색 인 행을 가져올 수 있습니다.mysql cross join에 있지 않습니까?

SELECT t1.id, col 
FROM extra as e INNER JOIN your_table as t1 USING (id) 
CROSS JOIN your_table as t2 USING (id) 
CROSS JOIN your_table as t3 USING (id) 
CROSS JOIN your_table as t4 USING (id) 
CROSS JOIN your_table as t5 USING (id) 
WHERE t1.color = 'blue' and t2.color = 'purple' and t3.color= 'green' and t4.color= 'white' and t5.color= 'black' 

! = 또는 NOT IN을 사용하려고하면 작동하지 않는 것 같습니다. 색상이 파란색, 보라색, 녹색, 흰색 (검정이 아닌)이되도록 쿼리를 작성하려면 어떻게해야합니까?

select e.id 
from extra as e 
where exists (select null from your_table as t where t.id = e.id and t.color = 'blue') 
    and exists (select null from your_table as t where t.id = e.id and t.color = 'purple') 
    and exists (select null from your_table as t where t.id = e.id and t.color = 'green') 
    and exists (select null from your_table as t where t.id = e.id and t.color = 'white') 
    and not exists (select null from your_table as t where t.id = e.id and t.color = 'black') 

또는 이런 일이 아마 더 효율적인 것 :

select e.id 
from extra as e 
where 4 = 
     (select count(*) 
     from your_table as t 
     where t.id = e.id 
      and t.color in ('blue', 'purple', 'green', 'white')) 
    and 0 = 
     (select count(*) 
     from your_table as t 
     where t.id = e.id 
      and t.color in ('black')) 

답변

2

당신의 라인을 따라 뭔가를 할 수 표준 가입처럼 보입니다

select * from cars join colors where cars.colorid = colors.colorid where colors.color != 'black' 
+1

그래도 효과가 있지만 놀랍게도 실제로는 더 효율적입니다. 두 번째 쿼리보다 약 2-3 배 빠릅니다. 그러나 본래의 크로스 조인은 처음 것보다 약 2 배 빠릅니다. 이것은 존재하지 않는 무언가를 선택하는 비용입니까? – Roger

+0

''your_table'에 ('id','color') 색인을 추가 할 수 있습니다. –

+0

아, 문제가 될 것이라고 생각했습니다. ID가 인덱싱되었지만 두 번째 열은 인덱싱되지 않았습니다. 지금은 훨씬 빠릅니다. 두 쿼리 모두 거의 같은 속도 인 것처럼 보이지만 첫 번째 두 번째 쿼리에는 "종속 쿼리"가 적습니다. 따라서 더 나은 것으로 가정합니다. – Roger

0

내가 쿼리를과 복잡함을 생각, 당신은 무엇을하려고

+0

두 번째가 AND이고 어디에 있다고 가정합니까? 그러나 그것은 참으로 효과가 없습니다. – Roger

2

나는 왜 당신이 사용하고 있는지 모른다. CROSS JOIN. 이것은 일반적으로 데카르트 제품을 생성하기위한 것입니다. 필요한 것은 모두 INNER JOIN 또는 간단히 JOIN입니다.

일부 데이터가 없는지 테스트하기 위해 일반적으로 OUTER JOIN을 사용합니다. 일치하는 항목이 없으면 t5은 NULL입니다.

SELECT t1.id, col 
FROM extra as e 
INNER JOIN your_table as t1 ON (e.id=t1.id AND t1.color = 'blue') 
INNER JOIN your_table as t2 ON (e.id=t2.id AND t2.color = 'purple') 
INNER JOIN your_table as t3 ON (e.id=t3.id AND t3.color = 'green') 
INNER JOIN your_table as t4 ON (e.id=t4.id AND t4.color = 'white') 
LEFT OUTER JOIN your_table as t5 ON (e.id=t5.id AND t5.color = 'black') 
WHERE t5.id IS NULL; 

당신은 위의 기술 사용은 상관 하위 쿼리를 사용하는 것보다 빠른 조인 맞아, 그것은 (적어도 MySQL의에서)이기도 어떤 사람들은 사용하십시오 GROUP BY 솔루션보다 빠른 :

SELECT e.id, col 
FROM extra as e 
INNER JOIN your_table AS t USING (id) 
WHERE t.color IN ('blue', 'purple', 'green', 'white') 
GROUP BY e.id 
HAVING COUNT(*) = 4; 

(이 쿼리는 "검은 색이 아닌"문제를 해결하지 못합니다. 기술을 설명하는 것입니다.)

+0

'cross join'과'inner join'은 MySQL에서는 동의어입니다 (그러나 ANSI SQL에서는 그렇지 않습니다). +1 왼쪽 외부 조인으로 좋은 아이디어. –

+0

멋진 방법, 다른 방법을 공유하고 계몽에 감사드립니다. – Roger

관련 문제