【问题标题】:in a select statement - how to include a filter after a function b4 the from clause在 select 语句中 - 如何在函数 b4 from 子句之后包含过滤器
【发布时间】:2017-12-07 05:55:39
【问题描述】:

我想通过“位置和产品”组合选择最佳销售人员。 第一次我排序和排名,然后我对“位置和产品”求和,然后我想通过“位置和产品”删除除顶级销售人员之外的所有内容,这样查询结果只包含“位置和产品”的顶级销售人员每个“位置和产品”组合的总销售额。

我没有的部分是“select Rank = 1” - 在“From”之后添加“where”子句不起作用:

Select Location, Product, Sales, Salesperson
       row_number() OVER (PARTITION BY concat(Location,Product) ORDER BY Sales desc) AS Rank,
       Sum(Sales) OVER(PARTITION BY concat(Location,Product)) AS Salesbylocprod
From Table A

【问题讨论】:

  • 您将当前查询放在子查询中,然后仅从该子查询中选择 rank = 1 的值(例如 select * from (my current query) as t where rank = 1;)。作为旁注,在PARTITION BY 子句中使用CONCAT 似乎没有必要;无论如何,您都可以按两列进行分区以获得相同的结果(并且在某些独特的场景中,两个不同位置和产品的串联是相同的,您会避免这种情况)。

标签: sql sql-server


【解决方案1】:

您可以使用子查询。此外,您不需要连接 partition by 的键:

Select Location, Product, Sales, Salesperson, Salesbylocprod
from (select a.*
             row_number() over (partition by Location, Product order by Sales desc) as seqnum,
             sum(Sales) over (partition by Location, Product) as Salesbylocprod
      From Table A
     ) a
where seqnum = 1;

请注意,我将列的名称从 rank 更改为 seqnumrank 有点暗示它是使用 rank() 函数计算的。这与row_number() 不同,因此名称具有误导性。

【讨论】:

    【解决方案2】:

    您也可以使用公用表表达式:

    ;WITH CTE 
         AS (SELECT *,
                    ROW_NUMBER() OVER(PARTITION BY Location,Product ORDER BY Sales DESC) AS RowNum,
                    SUM(Sales) OVER(PARTITION BY Location,Product) AS SalesByLocProd
             FROM TableA
            )
            SELECT Location,
                 Product,
                 Sales,
                 SalesPerson,
                 SalesByLocProd
            FROM CTE
            WHERE RowNum = 1;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-28
      • 1970-01-01
      • 1970-01-01
      • 2014-06-21
      • 2011-10-03
      • 2013-10-18
      • 2012-01-15
      相关资源
      最近更新 更多