2017-05-07 3 views
0

나는 이런 식으로 2 테이블을 가지고 있습니다. 하이브 쿼리를 실행 중이며 윈도우 기능이 하이브에 꽤 제한되어있는 것 같습니다.이것에 대한 최고의 하이브 SQL 쿼리

표 부서

id | name | 
1 | a | 
2 | b | 
3 | c | 
4 | d | 

표 시간 (내가 다른 새로 만든 테이블 시간에 가입해야하는 경우 매우 느린 과정을이 그래서 부하의 쿼리를 구축 할 수 있습니다.)

id | date | first | last | 
1 | 1992-01-01 | 1 | 1 | 
2 | 1993-02-02 | 1 | 2 | 
2 | 1993-03-03 | 2 | 1 | 
3 | 1993-01-01 | 1 | 3 | 
3 | 1994-01-01 | 2 | 2 | 
3 | 1995-01-01 | 3 | 1 | 

내가 필요

SELECT d.id,d.name, 
t.date AS firstdate, 
td.date AS lastdate 
FROM dbo.dept d LEFT JOIN dbo.time t ON d.id=t.id AND t.first=1 
LEFT JOIN time td ON d.id=td.id AND td.last=1 

어떻게 가장 최적화 된 답 : 이런 식으로 뭔가를 검색? 하나에서 수행됩니다

+1

넣어 일정한 비교 (즉,'t.first = 1')지도-감소 '절이 아니라'join' 절을 사용합니다. 이 외에도 이것은 매우 직설적입니다. – Donnie

+0

@Donnie이 하이브 테이블에서 새로운데,이 시간 테이블은 복잡한 'SELECT'쿼리에 의해 만들어졌습니다. 내가하려고하는 것은 시간 테이블을 한 번만 호출하는 것입니다. 가능합니까? @TimBiegeleisen이 작업을 수행하려면 하나의 쿼리가 필요합니다. 이 테이블은 무거운 작품에 의해 만들어진, 실제로 가장 좋은 접근 방식은 어쩌면 임시 테이블을 사용하고 있지만 어떻게 하이브에 사용하기 위해 최선인지 모르겠다. –

+0

@Donnie - 이것은 원래 쿼리와 논리적으로 동일하지 않습니다 –

답변

1

GROUP BY 작업은`곳에서 작업

select  id 
      ,max(name) as name 
      ,max(case when first = 1 then `date` end) as firstdate 
      ,max(case when last = 1 then `date` end) as lastdate 

from  (select  id 
         ,null as name 
         ,`date`   
         ,first   
         ,last 

      from  time 

      where  first = 1 
        or last = 1 

      union all 

      select  id 
         ,name   
         ,null as `date` 
         ,null as first 
         ,null as last 

      from  dept 
      ) t 

group by id 
; 

+----+------+------------+------------+ 
| id | name | firstdate | lastdate | 
+----+------+------------+------------+ 
| 1 | a | 1992-01-01 | 1992-01-01 | 
| 2 | b | 1993-02-02 | 1993-03-03 | 
| 3 | c | 1993-01-01 | 1995-01-01 | 
| 4 | d | (null)  | (null)  | 
+----+------+------------+------------+  
+0

업데이트 된 답변보기 (새로운 데이터 샘플에 맞게 조정) –

+0

감사합니다. 선생님, 저장하십시오! –

+1

반갑습니다. 추신. 성능을 향상시킬 수있는'WHERE' 절에 대한 업데이트 된 답변을 참조하십시오. –

0
select  d.id 
     ,max(d.name) as name 
     ,max(case when t.first = 1 then t.date end) as 'firstdate' 
     ,max(case when t.last = 1 then t.date end) as 'lastdate' 

from  dept d left join 
     time t on d.id = t.id 
where  t.first = 1 or t.last = 1 
group by d.id 
+0

저는 실제로 이미 이런 종류의 쿼리를 사용하고 있습니다. 쿼리 로직의 요지를 첫 번째 대답 인 'UNION ALL'에서 정상적인 'JOIN'btw보다 빠르게 얻습니다. 그러나 그럼에도 불구하고 고마워! –