2017-12-18 7 views
2

좀 더 복잡한 상황이지만 좀 더 쉽게 대답 할 수 있다고 생각합니다. TX에서 파란 트럭 만 운전하는 사람들에게 질문하려고한다고 가정 해 봅시다. Oracle 데이터베이스를 사용하고 있습니다.코드로 인해 사람들을 검색에서 제외시키는 방법

내가 가진 2 테이블 (State table) 및 (Truck table) 그들은 사람의 ID 번호에 가입

자동 테이블이 크다! 쿼리를 중단하거나 매우 오랫동안 실행하지 않으려는 경우 가장 큰 문제입니다.

상태 테이블

People  State 
------  ----- 
111  TX 
222  TX 
333  CA 

트럭 표

People  Date  Color 
------  ----  ------ 
111  1995  Orange 
111  1996  Blue 
111  1997  White 
111  2017  Blue 
111  2017  Gold 
222  2006  Blue 
333  2007  Blue 

그들이 트럭의 다른 색상을 가지고 있지 않았기 때문에 내가 돌아 원하는 것은 단지 222입니다.

222  2006  Blue 

표와 비슷한 것을 만드는 더 좋은 방법이 있다면 그 점도 알고 싶습니다.

+0

왜에만 222? 333도 왜 안 되니? 그렇다면 State 테이블은이 모든 측면에서 어떤 역할을합니까? 트럭 테이블의 날짜 열은 어때? 그들이 아무런 역할을하지 않으면, 그렇게 말하십시오 (또는 더 잘 말하면 질문에 포함하지 마십시오). – mathguy

+0

@mathguy, 333은 TX에 없습니다. –

+0

@JeffreyKemp - 오, 오케이, 나는 그 문제 진술서에서 그것을 놓쳤습니다. 나는 그것을 지금 본다. 감사! – mathguy

답변

-1

당신은 JOIN을 사용하여 테이블을 조회하여 시작할 수 있습니다 : 쿼리의 성능이 부족하면

SELECT People, Date, Color 
    FROM Truck 
    INNER JOIN State ON Truck.People = State.People 
    WHERE State.State = 'TX' 
    AND Truck.Color = 'Blue' 

는 다음 중 하나를 테이블에 적절한 인덱스를 추가 할 수 있습니다. 예를 들어, Color 속성의 트럭 테이블에 색인을 추가 할 수 있습니다.

select State.People 
from State 
join Truck on Truck.People = State.People 
where State.State = 'TX' 
and Truck.Color = 'Blue' 
and not exists (
    select null 
    from Truck t2 
    where t2.People = Truck.People 
    and t2.Color != 'Blue' 
); 

포함 인덱스 Truck (People, Color)에 아마 성능을 위해 충분 :

+0

이것은 111을 잘못 반환합니다 (111은 블루 트럭 만 * 않습니다 *). –

+0

해석 방법에 따라 다릅니다. OP는 예상 ​​결과 세트를 명확히해야합니다. – SandPiper

+0

좋은 캐치 @JeffreyKemp. 그것을 지적 주셔서 감사합니다. – STLDeveloper

0

가정의 모든 열은 NOT NULL 제약 조건이있다.

대안

고려해야 할 자세한 성능 튜닝을 위해 제가 실행 계획과 대략적인 데이터 볼륨을보고 시작하는 것

select State.People 
from State 
join Truck on Truck.People = State.People 
where State.State = 'TX' 
and Truck.Color = 'Blue' 
minus 
select Truck.People 
from Truck 
where Truck.People = Truck.People 
and Truck.Color != 'Blue'; 

.

0

는 (사후) 추가 : 그 사람들에 대한 truck 테이블에서 반환 아래의 솔루션 (이 경우 222)만을 people 식별자가 아닌 행 (또는 행!). 집계 쿼리 대신 전체 행이 필요한 경우 분석 함수를 사용할 수 있습니다. 수정하기 쉽지만, 원래 질문 아래에있는 Comment에 질문에 대답하십시오. END EDIT.

with 
    state_table (people, state) as (
    select 111, 'TX' from dual union all 
    select 222, 'TX' from dual union all 
    select 333, 'CA' from dual 
), 
    truck_table (people, dt, color) as (
    select 111, 1995, 'Orange' from dual union all 
    select 111, 1996, 'Blue' from dual union all 
    select 111, 1997, 'White' from dual union all 
    select 111, 2017, 'Blue' from dual union all 
    select 111, 2017, 'Gold' from dual union all 
    select 222, 2006, 'Blue' from dual union all 
    select 333, 2007, 'Blue' from dual 
) 
-- End of simulated inputs (for testing only, not part of the solution). 
-- SQL query begins BELOW THIS LINE. Use your actual table and column names 
select people 
from truck_table 
where people in (select people 
        from state_table 
        where state = 'TX' 
       ) 
group by people 
having count(case when color != 'Blue' or color is null then 1 end) = 0 
; 

    PEOPLE 
---------- 
     222 
1

사용하는 데 어떻습니까?여기

select state.people, state, color, count(color) 
from state, truck 
where state.people = truck.people 
and state.state = 'TX' 
and color = 'Blue' 
group by state.people, state, color 
having count(color) = 1 

는 바이올린에게 있습니다

http://sqlfiddle.com/#!4/89bdc/14

0

방법은 다음과 같이 하위 쿼리를 시도에 대해 :

select * from (select state.People, truck.Date, truck.Color, 
count(truck.People) over (partition by state.People) Cnt from state 
left join truck on state.People = truck.People and truck.Color = 'Blue' 
where state.State = 'TX') 
where cnt = 1