【问题标题】:Selective Aggregation (GROUP BY specific rows in the table)选择性聚合(GROUP BY 表中的特定行)
【发布时间】:2015-09-14 11:20:51
【问题描述】:

我有一个表格,我需要在其中对选择性(特定行)的金额进行分组。

按资产名称将基金 RLWP、RLNP/UL 和 RL Estate 中的行分组为一行。

将 > RLWP、RLNP/UL 和 RL Estate 的基金编号字段重命名为 RP,但我不想在基金名称不在(> RLWP、RLNP/UL 和 RL Estate)的地方分组或求和

Asset Name     |Entity Code  |Total SII Amount |Fund Number 
------------------------------------------------------------
GSW 4.375%     |1020OB       |1317697.53       |RLWP
GSW 4.375%     |1020OB       |1191368.74       |RLNP/UL
GSW 4.375%     |1020OB       |289004.18        |RL Estate
GSW 4.375%     |1020OB       |232360.70        |UFOIB
GSW 4.375%     |1020OB       |10102.50         |ABG
UKT 0.375%     |1020OB       |5555.20          |ABG
UKT 0.375%     |1020OB       |702743.3518      |RLWP
UKT 0.375%     |1020OB       |546232.3383      |RL Estate

我有 2 或 3 种方法可以做到这一点,但您能否建议最有效的方法,因为这只是存储过程中同一张表上其他几个计算的一部分。

我想到的一种方法是

Select 
    [Asset Name],
    [Entity Code],
    sum([Total SII Amount])
where 
    fundnumber in (RLWP, [RLNP/UL], RL Estate)
group by 
    [Asset Name], [Entity Code],

union

Select 
    [Asset Name],
    [Entity Code],
where 
    fundnumber not in (RLWP, [RLNP/UL], RL Estate)

稍后将 (RLWP, [RLNP/UL] ,RL Estate) 的列名称更新为 RP。

我想到了使用 CTE 或 Cross Apply 但无法真正组成查询的其他方式。

请提出建议。

【问题讨论】:

  • 您使用的是哪个版本的 SQL Server?
  • 使用 SQL 2012,您应该了解一下窗口函数。您可以使用带有 ORDER BY 的 OVER 子句和在 OVER 子句中使用 PARTITION BY 的分组总和来实现“运行总和”...
  • @Shnugo 你的意思是这样的吗:- SELECT [pK_AssetValuation],[Asset Name],[Entity Code],[Total SII Amount],FundNumber, sum([Total SII Amount]) OVER (ORDER BY [FundNumber] ROWS UNBOUNDED PRECEDING) AS RunningTotal FROM tmpADSTransform1 - 但这只是给出运行总数。我只想对几行进行求和和分组。
  • 是的,请尝试在 OVER 中的 ORDER BY 之前添加 PARTITION BY YourGroupColumn ,而不使用 commy :-)

标签: sql sql-server tsql group-by


【解决方案1】:

如果我理解正确,这可能是一个答案:

  SELECT [Asset Name],
         [Entity Code],
         SUM ([Total SII Amount]) [Total SII Amount],
         case  [Fund Number]
                when 'RLWP' then 'RP'
                when 'RLNP/UL' then 'RP'
                when 'RL Estate' then 'RP'
                else [Fund Number]
                end
            [Fund Number]
    FROM tab
GROUP BY [Asset Name],
         [Entity Code],
         case  [Fund Number]
                when 'RLWP' then 'RP'
                when 'RLNP/UL' then 'RP'
                when 'RL Estate' then 'RP'
                else [Fund Number]
                end

【讨论】:

  • @PDSQL - 这解决了这个问题,否则会导致这些问题按基金编号分组。
  • 如果基金编号是 ABG,那么您永远不想要总金额?即使资产名称和实体代码相同也不行?
  • 谢谢@Jon Tofte-Hansen 没有 RL 的呢?像 ABG - 我应该像我在问题中所说的那样将它们联合起来。 – PD SQL
  • @JonTofte-Hansen 是,如果 FundNumber 不在 ('RLWP' ,'RLNP/UL','RL Estate') 中,即使资产名称和实体代码是相同的?谢谢
【解决方案2】:

你问我一个例子,你在这里:只需粘贴到一个空的查询窗口并执行,适应你的需要......

DECLARE @Asset TABLE([Asset Name] VARCHAR(100),[Entity Code] VARCHAR(100), [Total SII Amount] DECIMAL(12,4),[Fund Number] VARCHAR(100) );
INSERT INTO @Asset VALUES
 ('GSW 4.375%','1020OB',1317697.53,'RLWP')
,('GSW 4.375%','1020OB',1191368.74,'RLNP/UL')
,('GSW 4.375%','1020OB',289004.18,'RL Estate')
,('GSW 4.375%','1020OB',232360.70,'UFOIB')
,('GSW 4.375%','1020OB',10102.50,'ABG')
,('UKT 0.375%','1020OB',5555.20,'ABG')
,('UKT 0.375%','1020OB',702743.3518,'RLWP')
,('UKT 0.375%','1020OB',546232.3383,'RL Estate');

--This comes back with all rows and a grouped sum at the end
WITH AssetsWithGroupedFundNumber AS
(
    SELECT *
          ,CASE [Fund Number]
                WHEN 'RLWP' THEN 'RP'
                WHEN 'RLNP/UL' THEN 'RP'
                WHEN 'RL Estate' THEN 'RP'
                ELSE [Fund Number]
           END AS FundNumberGrouped
    FROM @Asset
)
SELECT *
      ,SUM(a.[Total SII Amount]) OVER(PARTITION BY a.FundNumberGrouped) AS GroupSum
FROM AssetsWithGroupedFundNumber AS a;

--This comes back with a "normal" grouped sum
WITH AssetsWithGroupedFundNumber AS
(
    SELECT *
          ,CASE [Fund Number]
                WHEN 'RLWP' THEN 'RP'
                WHEN 'RLNP/UL' THEN 'RP'
                WHEN 'RL Estate' THEN 'RP'
                ELSE [Fund Number]
           END AS FundNumberGrouped
    FROM @Asset
)
SELECT a.FundNumberGrouped
      ,SUM(a.[Total SII Amount]) AS GroupSum
FROM AssetsWithGroupedFundNumber AS a
GROUP BY a.FundNumberGrouped

【讨论】:

  • 这很有帮助,我使用的是 CTE,因此它与我的代码内联,但是我必须合并所有 FundNumber 不在 ('RLWP' ,'RLNP/UL','RL Estate') 中,即对于 ABG - 即使资产名称和实体代码相同,也不需要分组或求和。我刚刚发布了一个 protoType 我在表中有数百列,其中许多列需要求和。
  • @PDSQL 如果有一些唯一的 rowID(无论如何),您可以将“ELSE [Fund Number]”更改为“ELSE [YourColumn]”(可能需要 CAST 到 VARCHAR(100)!) .这将为您想要单独处理的那些行返回一个唯一的分组值。
猜你喜欢
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
  • 2016-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-22
  • 2014-12-27
相关资源
最近更新 更多