假设:
需要过滤的两个查询:
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
。
我该如何解决这种情况?
答案 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 排序