结合MAX()和SUM()聚合的SQL查询

时间:2018-10-02 05:03:07

标签: sql oracle sum max

我尝试在这里和其他论坛中研究不同的主题,但似乎找不到解决我问题的方法。

我要实现的目标是“显示该客户收入最高的产品线的净销售额(以美元为单位)。使用标题:最佳销售。格式为999,999.99美元。

这是我到目前为止尝试过的:

SELECT cc.CustID, cc.CompanyName, cc.ContactName, pl.pl_id,to_char((sum(od.unitprice*od.quantity*(1-discount))), '$9,999,999.99') as rev
     FROM corp.customers cc JOIN corp.orders co ON (cc.CustID=co.CustID)
     LEFT OUTER JOIN corp.order_details od ON (co.orderID=od.orderID)
     LEFT OUTER JOIN corp.products cp ON (od.ProductID=cp.ProductID)
     LEFT OUTER JOIN corp.product_lines pl ON (cp.pl_id=pl.pl_id)
     GROUP BY cc.CustID, cc.CompanyName, cc.ContactName, pl.pl_id
     HAVING sum(od.unitprice*od.quantity*(1-discount))=
    ( 
       SELECT max(sum(od.unitprice*od.quantity*(1-discount)))
       FROM corp.customers cc JOIN corp.orders co ON (cc.CustID=co.CustID)
       JOIN corp.order_details od ON (co.orderID=od.orderID)
       JOIN corp.products cp ON (od.ProductID=cp.ProductID)
       JOIN corp.product_lines pl ON (cp.pl_id=pl.pl_id)
       GROUP BY cc.CustID, cc.CompanyName, cc.ContactName, pl.pl_id);

这仅给我一个输出,表示所有客户的最高收入,但是我希望它根据该客户的每个产品系列显示最高的收入。

结果如下所示。

CustID  | Company Name  | Contact Name  | PL_ID | Revenue
QUICK   | QUICK-Stop    | Horst Kloss   | 1     | $37,161.63

我希望它显示类似的东西。

CustID  | Company Name  | Contact Name  | PL_ID | Revenue
QUICK   | QUICK-Stop    | Horst Kloss   | 1     | $37,161.63
QS      | QUICK-Start   | Clark Stone   | 2     | $50,000.00
QUI     | QUICK         | Mary Haynes   | 1     | $60,000.00
QShelf  | QUICK-Shelf   | Doreen Lucas  | 4     | $35,161.63

感谢您的帮助。谢谢!

2 个答案:

答案 0 :(得分:1)

此查询使用您的原始查询,rank()函数按转速列排序以及仅获得最高转速的选择。如果您有多行具有相同的rev值,则将提供多行。如果只想将rank()更改为row_number()。

您也可以使用CTE代替嵌套查询,不会有任何区别。

select CustID, CompanyName, ContactName, pl_id, rev from (
select CustID, CompanyName, ContactName, pl_id, to_char(rev, '$9,999,999.99') as rev,
    rank() over(order by rev desc) r
from (
    SELECT cc.CustID, cc.CompanyName, cc.ContactName, pl.pl_id,
        sum(od.unitprice*od.quantity*(1-discount)) as rev
    FROM corp.customers cc JOIN corp.orders co ON (cc.CustID=co.CustID)
    LEFT OUTER JOIN corp.order_details od ON (co.orderID=od.orderID)
    LEFT OUTER JOIN corp.products cp ON (od.ProductID=cp.ProductID)
    LEFT OUTER JOIN corp.product_lines pl ON (cp.pl_id=pl.pl_id)
    GROUP BY cc.CustID, cc.CompanyName, cc.ContactName, pl.pl_id
) q
) q2 where r=1

答案 1 :(得分:0)

由于您没有向我们提供表的样本输入数据,因此我们提出了一个简单的示例,希望您可以使用它来修改查询:

<xsl:variable name="id" select="cac:AdditionalDocumentReference/cbc:ID" />
<xsl:value-of select='$QueryResult[ac_name = $id]/obj'/>

这将显示所有具有最高总和(val)的id2值。如果不想显示所有绑定的行,则可以使用WITH sample_data AS (SELECT 1 ID, 1 id2, 10 val FROM dual UNION ALL SELECT 1 ID, 1 id2, 20 val FROM dual UNION ALL SELECT 1 ID, 2 id2, 30 val FROM dual UNION ALL SELECT 1 ID, 2 id2, 40 val FROM dual UNION ALL SELECT 2 ID, 1 id2, 50 val FROM dual UNION ALL SELECT 2 ID, 2 id2, 60 val FROM dual UNION ALL SELECT 2 ID, 3 id2, 60 val FROM dual) SELECT ID, id2, max_sum_val FROM (SELECT ID, id2, SUM(val) sum_val, MAX(SUM(val)) OVER (PARTITION BY ID) max_sum_val FROM sample_data GROUP BY ID, id2) WHERE sum_val = max_sum_val; ID ID2 MAX_SUM_VAL ---------- ---------- ----------- 1 2 70 2 2 60 2 3 60 分析函数来代替:

row_number()

ETA:

这意味着您的查询最终将类似于:

WITH sample_data AS (SELECT 1 ID, 1 id2, 10 val FROM dual UNION ALL
                     SELECT 1 ID, 1 id2, 20 val FROM dual UNION ALL
                     SELECT 1 ID, 2 id2, 30 val FROM dual UNION ALL
                     SELECT 1 ID, 2 id2, 40 val FROM dual UNION ALL
                     SELECT 2 ID, 1 id2, 50 val FROM dual UNION ALL
                     SELECT 2 ID, 2 id2, 60 val FROM dual UNION ALL
                     SELECT 2 ID, 3 id2, 60 val FROM dual)
SELECT ID,
       id2,
       max_sum_val
FROM   (SELECT ID,
               id2,
               SUM(val) sum_val,
               row_number() OVER (PARTITION BY ID ORDER BY SUM(val) DESC, id2) rn
        FROM   sample_data
        GROUP BY ID, id2)
WHERE  rn = 1;

        ID        ID2 MAX_SUM_VAL
---------- ---------- -----------
         1          2          70
         2          2          60