s-s-rS:需要将项目和子项目分组和汇总到一条记录中

Posted

技术标签:

【中文标题】s-s-rS:需要将项目和子项目分组和汇总到一条记录中【英文标题】:s-s-rS: Need to group & sum items & sub items into one record 【发布时间】:2015-04-10 03:20:38 【问题描述】:

我在创建一份报告时遇到了一个 s-s-rs 问题,该报告可以将相似的项目分组和汇总在一起(我知道在某些方面,这个要求没有意义,但这是客户想要的)。

我有一个项目表(即产品)。在某些情况下,项目可以是另一个项目的组件(称为“套件”)。在这种情况下,我们将套件本身、“父项”和套件中的组件称为“子项”。在我们的 Items 表中,我们有一个名为“Parent_Item_Id”的字段。子项的记录包含父项的项 ID。因此,我的数据库示例如下:

ItemId | Parent_Item_Id | Name   | QuantityAvailable
----------------------------------------
1      | NULL           | Kit A  | 10
2      | 1              | Item 1 | 2
3      | 1              | Item 2 | 3
4      | NULL           | Kit B  | 4
5      | 4              | Item 3 | 21
6      | NULL           | Item 4 | 100

第 2 和第 3 项是“套件 A”的子项,第 5 项是“套件 B”的子项,第 6 项只是一个独立项。

因此,在我的报告中,客户希望在一行中查看套件及其组件的总和,并按父项分组。因此,报告的示例如下:

Name   | Available Qty
--------------------------
Kit A  | 15
Kit B  | 25
Item 4 | 100

知道如何将报告设置为正确分组吗?

提前致谢。

【问题讨论】:

对不起,我应该解释一下,我希望在 s-s-rs 报告中而不是在查询中对 tablex 本身进行分组。这个查询只是我想要实现的一个示例。实际上,查询是一个巨大的预先存在的查询,提取了大量信息。我最安全的方法是让查询保持原样,并尝试在报告本身内分组,如果可能的话。所以我需要按“parent_item_id”在报告中分组,但还要包括父项本身,并确保显示的项目名称是父项的名称 抱歉造成误解 【参考方案1】:

您可以尝试这种方式来获取套件及其组件的总和。

SELECT A.Name,A.QuantityAvailable+isnull(B.QuantityAvailable,0) AS [Available Qty] 
FROM ItemTable A
LEFT JOIN 
(
    SELECT Parent_Item_Id
    ,SUM(QuantityAvailable) as QuantityAvailable 
    FROM ItemTable
    WHERE Parent_Item_Id IS NOT null
    GROUP BY Parent_Item_Id 
)B
ON A.ItemId=B.Parent_Item_Id
WHERE A.Parent_Item_Id IS NULL

输出

Name    Available Qty
Kit A   15
Kit B   25
Item 4  100

【讨论】:

【参考方案2】:
select name, sum(quantityavailable) as available_qty
  from (select name, quantityavailable
          from tbl
         where parent_item_id is null
        union all
        select y.name, x.quantityavailable
          from tbl x
          join tbl y
            on x.parent_item_id = y.itemid) x
 group by name

小提琴: http://sqlfiddle.com/#!6/36871/3/0

【讨论】:

【参考方案3】:

在您的数据集中执行会容易得多。

样本数据:

WITH items
AS (
SELECT
     1 AS ItemId
    ,NULL AS Parent_Item_Id
    ,'Kit A' AS Name
    ,10 AS QuantityAvailable

UNION ALL

SELECT
     2 AS ItemId
    ,1 AS Parent_Item_Id
    ,'Item 1' AS Name
    ,2 AS QuantityAvailable

UNION ALL

SELECT
     3 AS ItemId
    ,1 AS Parent_Item_Id
    ,'Item 2' AS Name
    ,3 AS QuantityAvailable

UNION ALL

SELECT
     4 AS ItemId
    ,NULL AS Parent_Item_Id
    ,'Kit B' AS Name
    ,4 AS QuantityAvailable

UNION ALL

SELECT
     5 AS ItemId
    ,4 AS Parent_Item_Id
    ,'Item 3' AS Name
    ,21 AS QuantityAvailable

UNION ALL

SELECT
     6 AS ItemId
    ,NULL AS Parent_Item_Id
    ,'Item 4' AS Name
    ,100 AS QuantityAvailable
)

查询:

 SELECT
         parent.Name
        ,parent.QuantityAvailable + ISNULL(child.QuantityAvailable, 0) AS [Available Qty]
    FROM items parent
        LEFT JOIN (
                SELECT
                    Parent_Item_Id
                    ,SUM(QuantityAvailable) AS QuantityAvailable
                FROM items
                WHERE Parent_Item_Id IS NOT NULL
                GROUP BY Parent_Item_Id
                ) AS child
            ON parent.ItemId = child.Parent_Item_Id
    WHERE parent.Parent_Item_Id IS NULL

【讨论】:

【参考方案4】:

如果您的查询非常复杂,那么使用Common Table Expression 来创建结果的类似表的临时对象怎么样?然后,对您的问题的基于 SQL 的答案将与应用其他答案的子查询技术之一一样简单。

如果这真的不适合你,我可能会在你的 tablix 中创建一个组,其中的 group by 表达式如下:

=iif(isNothing(Parent_Item_Id.Value), ItemId, Parent_Item_ID)

这会将父项与其子项组合在一起,您可以在组级别执行 Sum() 函数。要获取父项的名称,您可以使用如下表达式:

=max(iif(isNothing(Parent_Item_Id.Value), Name.Value, ""))

【讨论】:

以上是关于s-s-rS:需要将项目和子项目分组和汇总到一条记录中的主要内容,如果未能解决你的问题,请参考以下文章

s-s-rS 仅对图表上的一个值进行分组

s-s-rS 2008 - 分组集?

计算 s-s-rS 分组值

s-s-rS 按多个字段和分组分组

iOS 从零到一搭建组件化项目框架

在 s-s-rS 矩阵报告中获取前 20 行,其余在第 21 行