0

我有一个用于对库存进行个别审计的数据表。每个审计都有一个位置、一个期望值、一个方差值和一些其他在这里并不重要的数据。

我正在为 Cognos 11 编写一个查询,它总结了一周的这些审计。目前,它按位置类将所有内容汇总为总和。我的问题是单个位置可能有多个审计,虽然我希望方差字段对所有审计的数据求和,无论它是否是该位置的第一个计数,我只想要不同位置的预期值(即只有 SUM位置不同的预期值)

以下是查询的简化版本。这甚至可能吗,还是我必须在 Cognos 中编写一个单独的查询并使其成为两个必须在事后合并的报告?您可能会说,我对 SQL 和 Cognos 还很陌生。

SELECT COALESCE(CASE 
                WHEN location_class = 'A'
                    THEN 'Active'
                WHEN location_class = 'C'
                    THEN 'Active'
                WHEN location_class IN (
                        'R'
                        ,'0'
                        )
                    THEN 'Reserve'
                END, 'Grand Total') "Row Labels"
        ,SUM(NVL(expected_cost, 0)) "Sum of Expected Cost"
        ,SUM(NVL(variance_cost, 0)) "Sum of Variance Cost"
        ,SUM(ABS(NVL(variance_cost, 0))) "Sum of Absolute Cost"
        ,COUNT(DISTINCT location) "Count of Locations"
        ,(SUM(NVL(variance_cost, 0)) / SUM(NVL(expected_cost, 0))) "Variance"
    FROM audit_table
    WHERE audit_datetime <= #prompt('EndDate') # audit_datetime >= #prompt('StartDate') #
    GROUP BY ROLLUP(CASE 
                WHEN location_class = 'A'
                    THEN 'Active'
                WHEN location_class = 'C'
                    THEN 'Active'
                WHEN location_class IN (
                        'R'
                        ,'0'
                        )
                    THEN 'Reserve'
                END)
    ORDER BY 1 ASC

这就是我希望最终得到的结果:

最终目标

谢谢你的帮助!

4

2 回答 2

1

您是否尝试过查看 SQL 中的OVER子句?它允许您在结果集中使用窗口函数,以便您可以根据特定条件获取聚合。这可能会有所帮助,因为您似乎试图根据更大分组中的不同分组来获取数据总和。

例如,假设我们有以下数据集:

group1      group2      val         dateadded
----------- ----------- ----------- -----------------------
1           1           1           2020-11-18
1           1           1           2020-11-20
1           2           10          2020-11-18
1           2           10          2020-11-20
2           3           100         2020-11-18
2           3           100         2020-11-20
2           4           1000        2020-11-18
2           4           1000        2020-11-20

使用单个查询,我们可以返回“group1”上“val”的总和以及“group2”中第一个(基于日期时间)“val”记录的总和:

declare @table table (group1 int, group2 int, val int, dateadded datetime)
insert into @table values (1, 1, 1, getdate())
insert into @table values (1, 1, 1, dateadd(day, 1, getdate()))
insert into @table values (1, 2, 10, getdate())
insert into @table values (1, 2, 10, dateadd(day, 1, getdate()))
insert into @table values (2, 3, 100, getdate())
insert into @table values (2, 3, 100, dateadd(day, 1, getdate()))
insert into @table values (2, 4, 1000, getdate())
insert into @table values (2, 4, 1000, dateadd(day, 1, getdate()))

select t.group1, sum(t.val) as group1_sum, group2_first_val_sum
from @table t
inner join
(
    select group1, sum(group2_first_val) as group2_first_val_sum
    from
    (
        select group1, val as group2_first_val, row_number() over (partition by group2 order by dateadded) as rownumber
        from @table
    ) y
    where rownumber = 1
    group by group1
    
) x on t.group1 = x.group1
group by t.group1, x.group2_first_val_sum

这将返回以下结果集:

group1      group1_sum  group2_first_val_sum
----------- ----------- --------------------
1           22          11
2           2200        1100

连接表中最内部的子查询根据“group2”对数据集中的行进行编号,导致记录在“rownum”列中具有“1”或“2”,因为每个“组 2”。

下一个子查询获取该数据并过滤掉所有不是第一个 (rownum = 1) 的行,并对“val”数据求和。

主查询从主表中获取每个“group1”中“val”的总和,然后连接子查询表以获取每个“group2”中仅第一条记录的“val”总和。

有更有效的方法来编写它,例如将“group1”值的总和移动到 SELECT 语句中的子查询中,以摆脱嵌套的表子查询之一,但我想展示如何在没有子查询的情况下做到这一点选择语句。

于 2020-11-18T23:57:42.867 回答
0

您是否尝试过像这样将 distinct 放在底部?

(SUM(NVL(variance_cost,0)) / SUM(NVL(expected_cost,0))) "方差",

COUNT(DISTINCT location) "位置计数"

FROM 审计表

于 2020-11-16T17:37:51.170 回答