2011-03-24 6 views
24

감안할 때 :SQL Server : WHERE 절이있는 두 개의 쿼리로 UNION을 사용하는 방법?

select top 2 t1.ID, t1.ReceivedDate 
    from Table t1 
where t1.Type = 'TYPE_1' 
order by t1.ReceivedDate desc 

그리고 : 필터링이 필요

두 쿼리

select top 2 t2.ID 
    from Table t2 
where t2.Type = 'TYPE_2' 
order by t2.ReceivedDate desc 

별도로를,이 내가 찾고있어 ID의를 반환 : (13, 11 및 12, 6)

기본적으로 두 개의 특정 ty에 대한 가장 최근의 두 레코드가 필요합니다. 데이터.

나는이 두 쿼리 함께과 같이 노동 조합하려는 :

select top 2 t1.ID, t2.ReceivedDate 
    from Table t1 
where t1.Type = 'TYPE_1' 
order by ReceivedDate desc 
union 
select top 2 t2.ID 
    from Table t2 
where t2.Type = 'TYPE_2' 
order by ReceivedDate desc 

문제 :

문제는이 경우 첫 번째 selectorder by 절을 가질 수 없기 때문에이 쿼리가 잘못이다 받고있는 것은 unioned입니다. 그리고 order by이없는 top 2을 가질 수 없습니다.

이 상황을 어떻게 해결할 수 있습니까?

+2

내 생각에 '주문'은 '어디서'가 아닌지에 문제가있는 것 같습니다. –

답변

37
당신은 당신의 첫번째 노력이 유효 이유 (부품 그들을 별칭 및 하위 쿼리로 사용할 수 있어야합니다

때문에 처음 두 개의 열 (ID 및 ReceivedDate)하지만, 두 번째 단 한 하나 (ID 있었다 선택) - 또한, 유형은 SQL Server의 예약어이며, 당신이) 열 이름으로 그것을했다으로 사용할 수 없습니다 :

declare @Tbl1 table(ID int, ReceivedDate datetime, ItemType Varchar(10)) 
declare @Tbl2 table(ID int, ReceivedDate datetime, ItemType Varchar(10)) 

insert into @Tbl1 values(1, '20010101', 'Type_1') 
insert into @Tbl1 values(2, '20010102', 'Type_1') 
insert into @Tbl1 values(3, '20010103', 'Type_3') 

insert into @Tbl2 values(10, '20010101', 'Type_2') 
insert into @Tbl2 values(20, '20010102', 'Type_3') 
insert into @Tbl2 values(30, '20010103', 'Type_2') 

SELECT a.ID, a.ReceivedDate FROM 
(select top 2 t1.ID, t1.ReceivedDate 
    from @tbl1 t1 
    where t1.ItemType = 'TYPE_1' 
    order by ReceivedDate desc 
) a 
union 
SELECT b.ID, b.ReceivedDate FROM 
(select top 2 t2.ID, t2.ReceivedDate 
    from @tbl2 t2 
    where t2.ItemType = 'TYPE_2' 
    order by t2.ReceivedDate desc 
) b 
+3

감사합니다. 이것은 내가 필요한 것입니다! – DJTripleThreat

+0

@DJTripleThreat : 편집하기 전에 수락했습니다. :) –

0

처음 두 개의 "선택 사항"과 "조합"에 대해보기를 작성하십시오.

+2

-1 두 개의보기를 선택하여 조합하는 것은 잘못된 것처럼 보입니다. –

+0

+1이 답변은 기술적으로 정확하기 때문에 최선의 해결책은 아닙니다. – DJTripleThreat

+0

@Ken White 그들이 가장 좋은 해결책이 아니기 때문에 대답을 투표하는 것이 좋은 생각이라고 생각하십니까? 30 초 안에 기술적으로 올바른 솔루션을 제공하며 코드가 필요 없습니다. @DJTripleThreat : 전문적인 태도에 감사드립니다. –

5
declare @T1 table(ID int, ReceivedDate datetime, [type] varchar(10)) 
declare @T2 table(ID int, ReceivedDate datetime, [type] varchar(10)) 

insert into @T1 values(1, '20010101', '1') 
insert into @T1 values(2, '20010102', '1') 
insert into @T1 values(3, '20010103', '1') 

insert into @T2 values(10, '20010101', '2') 
insert into @T2 values(20, '20010102', '2') 
insert into @T2 values(30, '20010103', '2') 

;with cte1 as 
(
    select *, 
    row_number() over(order by ReceivedDate desc) as rn 
    from @T1 
    where [type] = '1' 
), 
cte2 as 
(
    select *, 
    row_number() over(order by ReceivedDate desc) as rn 
    from @T2 
    where [type] = '2' 
) 
select * 
from cte1 
where rn <= 2 
union all 
select * 
from cte2 
where rn <= 2 
+1

+1 @Mikael. 이것도 좋은 예입니다! – DJTripleThreat

8
select * from 
(
    select top 2 t1.ID, t1.ReceivedDate 
    from Table t1 
    where t1.Type = 'TYPE_1' 
    order by t1.ReceivedDate de 
) t1 
union 
select * from 
(
    select top 2 t2.ID 
    from Table t2 
    where t2.Type = 'TYPE_2' 
    order by t2.ReceivedDate desc 
) t2 

또는 CTE에게 (SQL 서버 2005 +)

를 사용하여
;with One as 
(
    select top 2 t1.ID, t1.ReceivedDate 
    from Table t1 
    where t1.Type = 'TYPE_1' 
    order by t1.ReceivedDate de 
) 
,Two as 
(
    select top 2 t2.ID 
    from Table t2 
    where t2.Type = 'TYPE_2' 
    order by t2.ReceivedDate desc 
) 
select * from One 
union 
select * from Two 
+1

나를 위해 일하는 것은 매력처럼 !!! –

4

질문과 대답의 기본 전제가 잘못되었습니다. union의 모든 Select에는 where 절이있을 수 있습니다. 오류를주는 첫 번째 쿼리의 ORDER BY입니다.

+0

내 의견 = 15 자이지만이 답변입니다. –

0

UNION 내의 각 SELECT 문에는 동일한 수의 열이 있어야합니다. 열은 유사한 데이터 유형을 가져야합니다. 또한 각 SELECT.의 열은 동일한 순서 여야합니다. 당신은

을 선택하는

t1.ID, t2.ReceivedDate 테이블 T1에서 잘못된

조합

테이블 T2에서

t2.ID

.

은 그래서 당신은 쓸 필요가

t1.ID, t1.ReceivedDate 테이블 T1에서

당신이 여기에 하위 쿼리를 사용할 수 있습니다 t2.ID, t2.ReceivedDate 테이블 T1에서 조합

SELECT tbl1.ID, tbl1.ReceivedDate FROM 
     (select top 2 t1.ID, t1.ReceivedDate 
     from tbl1 t1 
     where t1.ItemType = 'TYPE_1' 
     order by ReceivedDate desc 
    ) tbl1 
union 
    SELECT tbl2.ID, tbl2.ReceivedDate FROM 
    (select top 2 t2.ID, t2.ReceivedDate 
     from tbl2 t2 
     where t2.ItemType = 'TYPE_2' 
     order by t2.ReceivedDate desc 
    ) tbl2 

그래서 두 테이블 모두에서 기본적으로 유일한 값만 반환합니다.

2

문제가 아닌 문제를 해결하려고 시도하면 대답이 오해의 소지가 있습니다. 실제로 UNION의 각 세그먼트에 WHERE 절이있을 수 있습니다. 마지막 세그먼트를 제외하고는 ORDER BY를 사용할 수 없습니다. 따라서이 작업을해야합니다 ...

select top 2 t1.ID, t1.ReceivedDate 
from Table t1 
where t1.Type = 'TYPE_1' 
-----remove this-- order by ReceivedDate desc 
union 
select top 2 t2.ID, t2.ReceivedDate --- add second column 
    from Table t2 
where t2.Type = 'TYPE_2' 
order by ReceivedDate desc 
+0

첫 번째 쿼리의 'TOP 2'에는 첫 번째 'ORDER BY' – OGHaza

관련 문제