Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Server: How to use UNION with two queries that BOTH have a WHERE clause?

Given:

Two queries that require filtering:

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

And:

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

Separately, these return the IDs I'm looking for: (13, 11 and 12, 6)

Basically, I want the two most recent records for two specific types of data.

I want to union these two queries together like so:

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 

Problem:

The problem is that this query is invalid because the first select cannot have an order by clause if it is being unioned. And it cannot have top 2 without having order by.

How can I fix this situation?

like image 427
aarona Avatar asked Mar 24 '11 23:03

aarona


People also ask

Can we use WHERE clause with UNION?

Using the Where Clause With the UNION OperatorWe can use the WHERE clause in either one or both of the SELECT statements to filter out the rows being combined. We can also use the WHERE clause in only one of the SELECT statements in the UNION.

How do you UNION multiple queries?

To combine result set of two or more queries using the UNION operator, these are the basic rules that you must follow: First, the number and the orders of columns that appear in all SELECT statements must be the same. Second, the data types of columns must be the same or compatible.

Which operation can be used to UNION of two queries?

You can combine multiple queries using the set operators UNION , UNION ALL , INTERSECT , and MINUS . All set operators have equal precedence. If a SQL statement contains multiple set operators, then Oracle Database evaluates them from the left to right unless parentheses explicitly specify another order.


1 Answers

You should be able to alias them and use as subqueries (part of the reason your first effort was invalid was because the first select had two columns (ID and ReceivedDate) but your second only had one (ID) - also, Type is a reserved word in SQL Server, and can't be used as you had it as a column name):

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 
like image 75
Ken White Avatar answered Sep 19 '22 22:09

Ken White