【问题标题】:Conditional Max in SQLSQL中的条件最大值
【发布时间】:2011-09-17 15:35:52
【问题描述】:

我必须在 SQL Server 中进行以下查询:

SELECT EmployeeID, 
       TotalQuantity AS TotalQty, 
       TotalSales, 
       MAX(CASE WHEN MonthNumber = MAX(MonthNumber)
           THEN TotalSales END) as RecentMonthSale
FROM vwSales 
GROUP BY EmployeeID, TotalQuantity , TotalSales

但它给了我错误:

Cannot perform an aggregate function on an expression
containing an aggregate or a subquery.

输入视图如下:

EmployeeID    TotaSales MonthNumber
  1             4000      1
  1             6000      2
  2             8500      1
  2             6081      2 

期望的输出:

EmployeeID    TotalSale     RecentMonthSale
  1            10000            6000
  2            14581            6081
  3            11458            1012 

我想在我的输出EmployeeID, TotalQuantity TotalSale RecentMonthSale 中有以下列我的视图有以下列EmployeeID TotalSale,TotalQuantity, MonthNumber

【问题讨论】:

  • 您能解释一下您希望查询显示的内容吗?
  • 该更新几乎没有解释任何内容。给出表的准确定义、视图的准确定义以及您希望查询返回什么(如“总销售额和每个员工的最近销售额)。

标签: sql sql-server tsql sql-server-2008 query-optimization


【解决方案1】:

此查询将显示您需要的输出,并且只会扫描表一次。

select EmployeeID, sum(TotalSales), sum(case when MaxMonth = 1 then TotalSales else 0 end) RecentMonthSales
from 
(
    select *, rank() over(order by MonthNumber desc) MaxMonth
    from
    (
        select EmployeeID, MonthNumber, sum(TotalSales) TotalSales
        from vwSales
        group by EmployeeID, MonthNumber
    ) tt
) tt
group by EmployeeID

【讨论】:

  • 只是为了好奇。视图会被 SQL Server 执行两次还是一次
  • @Tassadaque - 两次。但是对于MonthNumber 上的索引,这并不重要,因为它可能是一个非常快速的索引搜索。
  • @Tassadaque - 制作了只能访问表一次的版本。
  • 非常感谢! over函数的使用真的派上用场了!
【解决方案2】:
SELECT
    vw.EmployeeID,
    SUM(vw.TotalSale) as Total,
    Recent.RecentMonthSale
FROM
    vwSales vw
    LEFT JOIN
    (
        SELECT
            _vw.EmployeeID,
            _vw.TotalSale as RecentMonthSale
        FROM
            vwSales _vw
        INNER JOIN
        (
            SELECT EmployeeID, MAX(MonthNumber) as MaxMonth
            FROM vwSales
            GROUP BY EmployeeID
        ) _a
        on _vw.EmployeeID = _a.EmployeeID
        and _vw.MonthNumber = _a.MaxMonth
    ) Recent
    on Recent.EmployeeID = vw.EmployeeID
GROUP BY
    vw.EmployeeID,
    Recent.RecentMonthSale

如果您只是执行每个子查询并查看它们的结果,您应该对它的工作原理有一个很好的了解

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-13
    • 2018-11-11
    • 1970-01-01
    • 2015-11-04
    相关资源
    最近更新 更多