SQL Server:如何将UNION与两个具有WHERE子句的查询一起使用?

时间:2011-03-24 23:20:08

标签: sql-server union where-clause

假设:

需要过滤的两个查询:

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)

基本上,我想要两个特定类型数据的两个最新记录。

我想将这两个查询结合在一起:

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子句。如果没有top 2,则无法order by

我该如何解决这种情况?

8 个答案:

答案 0 :(得分:39)

您应该能够对它们进行别名并将其用作子查询(部分原因是您的第一次选择无效是因为第一个选择有两列(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

答案 1 :(得分:9)

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 Server 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

答案 2 :(得分: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

答案 3 :(得分:4)

问题和答案的基本前提是错误的。联合中的每个Select都可以有一个where子句。它是第一个查询中的ORDER BY,它给出了错误。

答案 4 :(得分:3)

答案是误导性的,因为它试图解决一个不成问题的问题。实际上,你可以在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

答案 5 :(得分:0)

在两个第一个“选择”和“联合”它们上创建视图。

答案 6 :(得分:0)

请注意,UNION中的每个SELECT语句必须具有相同的列数。列还必须具有类似的数据类型。此外,每个SELECT语句中的列必须具有相同的顺序。 你正在选择

  

t1.ID,t2.ReceivedDate     来自表t1

联合

  

t2.ID     来自表t2

这是不正确的。

所以你必须写

  表t1中的

t1.ID,t1.ReceivedDate   联盟   来自表t1的t2.ID,t2.ReceivedDate

你可以在这里使用子查询

 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 

因此默认情况下它将仅从两个表中返回不同的值。

答案 7 :(得分:0)

选择前 2 个 t1.ID、t2.ReceivedDate、1 个 SortBy 从表 t1 其中 t1.Type = 'TYPE_1' 联盟 选择前 2 个 t2.ID, 2 SortBy 从表 t2 其中 t2.Type = 'TYPE_2' 按 3,2 排序