【问题标题】:SUM FIRST_VALUE or SUM group by while still showing all rows?SUM FIRST_VALUE 或 SUM group by 同时仍显示所有行?
【发布时间】:2020-01-29 00:42:35
【问题描述】:

我有一张如下表:

InvoiceNum, CreditNum, ItemID,  TotalCreditDetail, TotalCredit, TotalCost, SumCreditDetailTaxed
001       , 001      , ITEM-A,  340              , 20811      , 20894.84 , 340
001       , 002      , ITEM-B,  0                , 20811      , 20894.84 , 20471
001       , 002      , ITEM-C,  4510             , 20811      , 20894.84 , 20471
001       , 002      , ITEM-D,  1424             , 20811      , 20894.84 , 20471
001       , 002      , ITEM-E,  2230             , 20811      , 20894.84 , 20471
001       , 002      , ITEM-F,  5225             , 20811      , 20894.84 , 20471
001       , 002      , ITEM-G,  3400             , 20811      , 20894.84 , 20471
001       , 002      , ITEM-H,  1242             , 20811      , 20894.84 , 20471
001       , 002      , ITEM-I,  2200             , 20811      , 20894.84 , 20471
001       , 002      , ITEM-J,   240             , 20811      , 20894.84 , 20471

我正在尝试获取带有“未分类信用”的列,基本上是与 ItemID 无关的信用。 TotalCredit 是 InvoiceNum 独有的,所以我可以通过减去 FIRST_VALUE(TotalCredit) OVER (PARTITION BY InvoiceNum) - SUM(TotalCreditDetail) OVER (PARTITION BY InvoiceNum) as UncategorizedCredit 得到这个数字吗?我想我可能已经回答了我自己关于如何计算 UncategorizedCredit 的问题,但我不确定。我今天才找到FIRST_VALUE。我目前正在使用SUM(CASE WHEN... ) 来计算它,但它很混乱,似乎需要我使用SUM() 进行分组,然后取消分组以获得报告所需的所有详细信息。

之后,我需要对未分类信用列求和,以获得 CrystalReports 中整个报表的总和。这是有点棘手的地方,因为报告按 ITEM 分组,InvoiceNum 002 可能有 ITEM-C 和 ITEM-D,InvoiceNum 003 可能有 ITEM-H 和 ITEM-I 等。现在我正在使用变量将报表详细信息中的数字添加到总数中。然后我想返回并从总计中减去任何未分类的信用。

我的问题是,如何在按 ITEM-ID 分组的报告中添加每个发票的值?我考虑使用一个数组来存储我已经求和的 InvoiceNum,但数组的最大值为 1000,并且在本报告中将远远超过这个数字。

我想我可以在从前一个 select 语句中选择的新 select 语句中使用 SUM(UncategorizedCredit) OVER() as TotalUncategorizedCredit

我不能使用嵌套选择,因为 CrystalReports 对数据应用了过滤器/where 子句,并且总数不准确。为了获得 TotalCreditDetail 和 SumCreditDetailTaxed,我目前正在使用 ~8-10 种不同类型的 JOINS,其中一些是 RIGHT OUTER JOIN (SELECT * FROM table) ON x = y。我面前实际上没有 SQL,明天会尝试 SUM,但如果 FIRST_VALUE 不起作用,那么我不确定还能做什么。

这可能只有一千美元的差异,但我正在努力解释一切。

【问题讨论】:

  • 请显示您的预期结果,以及您最近的查询尝试。

标签: sql sql-server tsql crystal-reports


【解决方案1】:

我想你想要:

select invoicenum,
       (TotalCredit - sum(TotalCreditDetail)) as uncategorizedCredit
from t
group by invoicenum, TotalCredit;

first_value() 实际上并不需要这样做——因为每一行的值都是相同的。因此,作为窗口函数,可以这样做:

select t.*,
       (max(TotalCredit) over (partition by invoicenum) -
        sum(TotalCreditDetail) over (partition by invoicenum)
       ) as uncategorizedCredit
from t;

您可以使用first_value() 代替min()/max()——但后者更易于键入。

【讨论】:

    【解决方案2】:

    戈登,

    感谢您的回复。我无法使用 group by,因为我需要取消分组的每一行以显示报告中的各个项目。但是,提醒我 FIRST_VALUE 与 MIN/MAX (doh) 相同对我的搜索有很大帮助。

    我设法解决了它,如果您好奇,这是我最终得到的 SQL 查询:

        SELECT 
        SUM(CASE WHEN ReportB.RowNum = 1 THEN UncategorizedCredit ELSE 0 END) OVER () as TotalUncategorizedCredit,
        *
    FROM (
            SELECT 
                FIRST_VALUE(TotalCredit) OVER (PARTITION BY InvoiceNum ORDER BY InvoiceNum) - SUM(TotalCreditDetail) OVER (PARTITION BY InvoiceNum Order BY InvoiceNum) as UncategorizedCredit,
                ROW_NUMBER() OVER (Partition by InvoiceNum ORDER BY InvoiceNum) as RowNum,
                InvoiceNum,
                CreditNum,
                TotalCreditDetail,
                TotalCredit,
                TotalCost,
                SumCreditDetailTaxed
            FROM (SELECT *  FROM [table]) as Report
    ) ReportB
    

    我需要添加一个由相同分区的 ROW_NUMBER() 列,然后使用 CASE WHEN 过滤 SUM,以便它仅在行号为 1 时添加它。

    感谢您的帮助。

    谢谢, 贾里德

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      • 2012-09-12
      • 2020-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多