Sql server 合并所有2个查询,同时对每个查询进行排序
如何合并所有2个查询,但在合并所有查询之前还要对每个查询进行排序? 我希望在sum[docextprice]desc订购结果后,每年都能获得前20名的结果 以下是我现在拥有的一个例子:Sql server 合并所有2个查询,同时对每个查询进行排序,sql-server,tsql,sql-server-2008-r2,Sql Server,Tsql,Sql Server 2008 R2,如何合并所有2个查询,但在合并所有查询之前还要对每个查询进行排序? 我希望在sum[docextprice]desc订购结果后,每年都能获得前20名的结果 以下是我现在拥有的一个例子: SELECT top 20 gm.[partnum] ,p.PartDescription ,sum([docextprice])[docextprice] ,year([invoicedate])year
SELECT top 20 gm.[partnum]
,p.PartDescription
,sum([docextprice])[docextprice]
,year([invoicedate])year
,'Eco Surfaces' product
FROM dbo.gm gm
JOIN dbo.Part p on gm.partnum = p.PartNum
WHERE gm.company = 'EII' and [invoicedate] BETWEEN '20100809' and '20101231'
and p.ClassID in ('mpe')
GROUP BY year([invoicedate]),gm.[partnum],p.PartDescription
ORDER BY year([invoicedate]),sum([docextprice]) desc
UNION ALL
SELECT top 20 gm.[partnum]
,p.PartDescription
--,gm.[prodcode]
--,p.ClassID
,sum([docextprice])[docextprice]
,year([invoicedate])year
,'Eco Surfaces' product
FROM dbo.gm gm
JOIN dbo.Part p on gm.partnum = p.PartNum
WHERE gm.company = 'EII' and [invoicedate] BETWEEN '20110101' and '20111231'
and p.ClassID in ('mpe')
GROUP BY year([invoicedate]),gm.[partnum],p.PartDescription
ORDER BY year([invoicedate]),sum([docextprice]) desc
显然,此查询不会,因为您不能在联接的两侧按顺序排列。在将结果合并之前,您可以使用公共表表达式保存这些结果:
WITH cte1
AS ( SELECT TOP 20
gm.[partnum] ,
p.PartDescription ,
SUM([docextprice]) [docextprice] ,
YEAR([invoicedate]) year ,
'Eco Surfaces' product
FROM dbo.gm gm
JOIN dbo.Part p ON gm.partnum = p.PartNum
WHERE gm.company = 'EII'
AND [invoicedate] BETWEEN '20100809' AND '20101231'
AND p.ClassID IN ( 'mpe' )
GROUP BY YEAR([invoicedate]) ,
gm.[partnum] ,
p.PartDescription
ORDER BY YEAR([invoicedate]) ,
SUM([docextprice]) DESC
),
cte2
AS ( SELECT TOP 20
gm.[partnum] ,
p.PartDescription
--,gm.[prodcode]
--,p.ClassID
,
SUM([docextprice]) [docextprice] ,
YEAR([invoicedate]) year ,
'Eco Surfaces' product
FROM dbo.gm gm
JOIN dbo.Part p ON gm.partnum = p.PartNum
WHERE gm.company = 'EII'
AND [invoicedate] BETWEEN '20110101' AND '20111231'
AND p.ClassID IN ( 'mpe' )
GROUP BY YEAR([invoicedate]) ,
gm.[partnum] ,
p.PartDescription
ORDER BY YEAR([invoicedate]) ,
SUM([docextprice]) DESC
)
SELECT *
FROM cte1
UNION ALL
SELECT *
FROM cte2
在将结果合并到一起之前,可以使用公共表表达式保存这些结果:
WITH cte1
AS ( SELECT TOP 20
gm.[partnum] ,
p.PartDescription ,
SUM([docextprice]) [docextprice] ,
YEAR([invoicedate]) year ,
'Eco Surfaces' product
FROM dbo.gm gm
JOIN dbo.Part p ON gm.partnum = p.PartNum
WHERE gm.company = 'EII'
AND [invoicedate] BETWEEN '20100809' AND '20101231'
AND p.ClassID IN ( 'mpe' )
GROUP BY YEAR([invoicedate]) ,
gm.[partnum] ,
p.PartDescription
ORDER BY YEAR([invoicedate]) ,
SUM([docextprice]) DESC
),
cte2
AS ( SELECT TOP 20
gm.[partnum] ,
p.PartDescription
--,gm.[prodcode]
--,p.ClassID
,
SUM([docextprice]) [docextprice] ,
YEAR([invoicedate]) year ,
'Eco Surfaces' product
FROM dbo.gm gm
JOIN dbo.Part p ON gm.partnum = p.PartNum
WHERE gm.company = 'EII'
AND [invoicedate] BETWEEN '20110101' AND '20111231'
AND p.ClassID IN ( 'mpe' )
GROUP BY YEAR([invoicedate]) ,
gm.[partnum] ,
p.PartDescription
ORDER BY YEAR([invoicedate]) ,
SUM([docextprice]) DESC
)
SELECT *
FROM cte1
UNION ALL
SELECT *
FROM cte2
您可以在没有工会的情况下做到这一点:
您可以在没有工会的情况下做到这一点:
您应该能够从原始脚本中删除第一个查询中的order by。批处理中只能有一条order by语句
SELECT top 20 gm.[partnum]
,p.PartDescription
,sum([docextprice])[docextprice]
,year([invoicedate])year
,'Eco Surfaces' product
FROM dbo.gm gm
JOIN dbo.Part p on gm.partnum = p.PartNum
WHERE gm.company = 'EII' and [invoicedate] BETWEEN '20100809' and '20101231'
and p.ClassID in ('mpe')
GROUP BY year([invoicedate]),gm.[partnum],p.PartDescription
UNION ALL
SELECT top 20 gm.[partnum]
,p.PartDescription
--,gm.[prodcode]
--,p.ClassID
,sum([docextprice])[docextprice]
,year([invoicedate])year
,'Eco Surfaces' product
FROM dbo.gm gm
JOIN dbo.Part p on gm.partnum = p.PartNum
WHERE gm.company = 'EII' and [invoicedate] BETWEEN '20110101' and '20111231'
and p.ClassID in ('mpe')
GROUP BY year([invoicedate]),gm.[partnum],p.PartDescription
ORDER BY year([invoicedate]),sum([docextprice]) desc
您应该能够从原始脚本中删除第一个查询中的order by。批处理中只能有一条order by语句
SELECT top 20 gm.[partnum]
,p.PartDescription
,sum([docextprice])[docextprice]
,year([invoicedate])year
,'Eco Surfaces' product
FROM dbo.gm gm
JOIN dbo.Part p on gm.partnum = p.PartNum
WHERE gm.company = 'EII' and [invoicedate] BETWEEN '20100809' and '20101231'
and p.ClassID in ('mpe')
GROUP BY year([invoicedate]),gm.[partnum],p.PartDescription
UNION ALL
SELECT top 20 gm.[partnum]
,p.PartDescription
--,gm.[prodcode]
--,p.ClassID
,sum([docextprice])[docextprice]
,year([invoicedate])year
,'Eco Surfaces' product
FROM dbo.gm gm
JOIN dbo.Part p on gm.partnum = p.PartNum
WHERE gm.company = 'EII' and [invoicedate] BETWEEN '20110101' and '20111231'
and p.ClassID in ('mpe')
GROUP BY year([invoicedate]),gm.[partnum],p.PartDescription
ORDER BY year([invoicedate]),sum([docextprice]) desc
如果你第一个时间段有5个结果,第二个时间段有35个结果,而不是第一个时间段前20名和第二个时间段前20名,我认为这不会给你期望的结果。对吗?@Dave.Gugg为什么不?如果第一个时间段结果只有5行,那么该年的RN将一直到5行,如果第二年到35行,那么该年的RN将一直到35行。对不起,我没解释清楚。看起来OP需要40个总结果,20个来自一个时间段20100809到20101231,20个来自另一个时间段20110101到20111231。如果数据是这样出现的,您的解决方案不能返回第一个时间段的前5行和第二个时间段的前35行吗?@Dave.Gugg不,我的答案不会这样,因为行数是按年份划分的,因此如果有那么多的结果,它将从每年返回20行year@Dave.Gugg对当然它在这种情况下有效,在您解释的情况下不起作用。这个答案是根据opI的sum[docextprice]desc要求订购结果后,我希望每年的前20个结果。如果第一个时间段的结果为5个,第二个时间段的结果为35个,我不认为这会给您带来期望的结果,而不是第一个时段的前20名和第二个时段的前20名。对吗?@Dave.Gugg为什么不?如果第一个时间段结果只有5行,那么该年的RN将一直到5行,如果第二年到35行,那么该年的RN将一直到35行。对不起,我没解释清楚。看起来OP需要40个总结果,20个来自一个时间段20100809到20101231,20个来自另一个时间段20110101到20111231。如果数据是这样出现的,您的解决方案不能返回第一个时间段的前5行和第二个时间段的前35行吗?@Dave.Gugg不,我的答案不会这样,因为行数是按年份划分的,因此如果有那么多的结果,它将从每年返回20行year@Dave.Gugg对当然它在这种情况下有效,在您解释的情况下不起作用。这个答案遵循的是“我想要每年前20名的结果”,在结果按op的sum[docextprice]desc要求排序之后