2010-04-21 6 views
15

쿼리를 수행하는 데 문제가 있습니다. 나는 두 개의 테이블을 가지고 있는데 하나는 요소 정보를 가지고 있고 다른 하나는 첫 번째 테이블의 요소와 관련된 레코드를 가지고있다. 아이디어는 요소 정보와 여러 레코드 정보를 같은 행에 얻는 것입니다.서브 쿼리를 재사용 할 수 있습니까?

구조는 다음과 같이 설명 될 수있다 :

table [ id, name ] 
[1, '1'], [2, '2'] 

table2 [ id, type, value ] 
[1, 1, '2009-12-02'] 
[1, 2, '2010-01-03'] 
[1, 4, '2010-01-03'] 
[2, 1, '2010-01-02'] 
[2, 2, '2010-01-02'] 
[2, 2, '2010-01-03'] 
[2, 3, '2010-01-07'] 
[2, 4, '2010-01-07'] 

을 그리고 이것은 내가 달성하고자하려는 것입니다 :

result [id, name, Column1, Column2, Column3, Column4] 

[1, '1', '2009-12-02', '2010-01-03', , '2010-01-03'] 
[2, '2', '2010-01-02', '2010-01-02', '2010-01-07', '2010-01-07'] 

다음 쿼리는 올바른 결과를 얻을 수 있지만, 그것은 나에게 매우 비효율적 인 것 같습니다 , 각 열에 대해 table2를 반복해야합니다. 어쨌든 하위 쿼리를 수행하고 다시 사용할 수 있습니까?

SELECT 
     a.id, 
     a.name, 
     (select min(value) from table2 t where t.id = subquery.id and t.type = 1 group by t.type) as Column1, 
     (select min(value) from table2 t where t.id = subquery.id and t.type = 2 group by t.type) as Column2, 
     (select min(value) from table2 t where t.id = subquery.id and t.type = 3 group by t.type) as Column3, 
     (select min(value) from table2 t where t.id = subquery.id and t.type = 4 group by t.type) as Column4 
FROM 
     (SELECT distinct id 
     FROM table2 t 
     WHERE (t.type in (1, 2, 3, 4)) 
      AND t.value between '2010-01-01' and '2010-01-07') as subquery 
     LEFT JOIN table a ON a.id = subquery.id 
+2

이가 어떤 데이터베이스입니다? 그리고 어떤 데이터베이스 버전 (예 : SQL Server 2000, 2005 또는 2008?) –

+0

[sql에서 하위 쿼리를 다시 사용하는 방법] 가능한 복제본 (http://stackoverflow.com/questions/14987317/how-to-reuse -a-sub-query-in-sql) –

답변

20

:

with minima as (select t.id, t.type, min(value) min_value 
       from table2 t 
       where t.type in (1,2,3,4) 
       group by t.id, t.type) 
select a.id, a.name, 
     (select min_value from minima where minima.id = subquery.id and minima.type = 1) as column1, 
     (select min_value from minima where minima.id = subquery.id and minima.type = 2) as column2, 
     (select min_value from minima where minima.id = subquery.id and minima.type = 3) as column3, 
     (select min_value from minima where minima.id = subquery.id and minima.type = 4) as column4 
from (select distinct id from table2 t where t.type in (1,2,3,4) and t.value between '2010-01-01' and '2010-01-07') as subquery 
    left join a on a.id = subquery.id 

실제로 어떤 혜택 (또는 지원 여부) 여부는 환경 및 데이터 집합에 따라 다릅니다.

또 다른 방법 :

select xx.id, a.name, xx.column1, xx.column2, xx.column3, xx.column4 
from (
     select id, 
      max(case type when 1 then min_value end) as column1, 
      max(case type when 2 then min_value end) as column2, 
      max(case type when 3 then min_value end) as column3, 
      max(case type when 4 then min_value end) as column4 
     from (select t.id, t.type, min(value) min_value 
      from table2 t 
      where t.type in (1,2,3,4) 
      group by t.id, t.type) minima 
     group by id 
) xx left join a on a.id = xx.id 
order by 1 
5

일부 데이터베이스 제품 (Oracle, SQL Server 2005, SQL Server 2008 등)은 공통 테이블 표현식 (CTE)을 생성하는 기능을 제공합니다. 그것으로 당신과 같이 하위 쿼리를 다시 사용할 수 있습니다 :

With Subquery As 
    (
    Select Id 
     , Min(Case When T.TypeId = 1 Then Value End) As MinType1 
     , Min(Case When T.TypeId = 2 Then Value End) As MinType2 
     , Min(Case When T.TypeId = 3 Then Value End) As MinType3 
     , Min(Case When T.TypeId = 4 Then Value End) As MinType4 
    From Table2 As T 
    Where T.Type In(1,2,3,4) 
     And T.Value Between '2010-01-01' And '2010-01-07' 
    Group By Id 
    ) 
Select A.Id, A.Name, S.MinType1, S.MinType2, S.MinType3, S.MinType4 
From Subquery As S 
    Left Join Table As A 
     On A.Id = S.Id 

보다이 크게 다르지 않을 것이다 부여 : 당신은 CTE (공통 테이블 식)로 집계을 취할 수

Select A.Id, A.Name, S.MinType1, S.MinType2, S.MinType3, S.MinType4 
From (
     Select Id 
      , Min(Case When T.TypeId = 1 Then Value End) As MinType1 
      , Min(Case When T.TypeId = 2 Then Value End) As MinType2 
      , Min(Case When T.TypeId = 3 Then Value End) As MinType3 
      , Min(Case When T.TypeId = 4 Then Value End) As MinType4 
     From Table2 As T 
     Where T.Type In(1,2,3,4) 
      And T.Value Between '2010-01-01' And '2010-01-07' 
     Group By Id 
     ) As S 
    Left Join Table As A 
     On A.Id = S.Id 
관련 문제