2011-03-24 31 views
24

考慮:SQL Server:如何使用UNION和兩個查詢都有WHERE子句?

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)

基本上,我想要兩個特定的最近兩個記錄數據的pes。

我想聯盟這兩個查詢等一起這樣:

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 

問題:

的問題是,這種查詢是無效的,因爲第一select不能有order by條款,如果它是正在unioned。如果沒有order by,它不能有top 2

我該如何解決這種情況?

+2

我想你的意思是,你有'順序''不''哪裏'的麻煩。 – 2011-03-24 23:39:19

回答

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 2011-03-24 23:43:33

+0

@DJTripleThreat:我在編輯之前接受了。 :) – 2011-03-24 23:46:13

0

創建兩個第一個「選擇」和「聯合」他們的意見。

+2

-1僅僅爲了選擇和合並而創建兩個視圖似乎是錯誤的。 – 2011-03-24 23:37:19

+0

+1,因爲這個答案在技術上是正確的,但它不是最好的解決方案。 – DJTripleThreat 2011-03-24 23:45:23

+0

@Ken White你真的認爲這是一個好主意,只是因爲它們不是最好的解決方案才能投票回答答案嗎?技術上正確的解決方案在30秒內完成,無需涉及任何代碼。 @DJTripleThreat:謝謝你的專業態度。 – 2011-03-25 09:24:37

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 2011-03-24 23:44:35

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

爲我工作就像一個魅力! – 2013-07-11 16:16:02

4

問題和答案的基本前提是錯誤的。在聯合中的每個選擇都可以有一個where子句。這是ORDER BY在第一個查詢中給出的錯誤。

+0

所以我的評論= 15個字符,但這是答案。 – 2014-03-07 17:04:00

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 CLAUSE。除最後一段以外,您不能擁有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 2016-09-16 01:53:42