Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 合并所有2个查询,同时对每个查询进行排序_Sql Server_Tsql_Sql Server 2008 R2 - Fatal编程技术网

Sql server 合并所有2个查询,同时对每个查询进行排序

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

如何合并所有2个查询,但在合并所有查询之前还要对每个查询进行排序? 我希望在sum[docextprice]desc订购结果后,每年都能获得前20名的结果

以下是我现在拥有的一个例子:

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要求排序之后