SQL 查询中的累积计算与分层计算或带条件逻辑的内联 Table 值函数?

Cumulative vs. Tiered Calculation in SQL Query or Inline Table Value Function with Conditional Logic?

我正在处理两个 table 数据,但使用不同的方法来导出下面两个不同的所需输出。

第一个是累积层计算,第二个只是基于范围的分层查找。我需要能够return 计算行项目事务,该计算基于某些使用外键到其他维度 table 的 JOINS,即帐户和区域以及层类型。例如,单个帐户可以根据区域 and/or 帐户的 ID 进行累积或分层计算。

Link 到 DB Fiddle

Type ID Name
1 Cumulative
2 Tiered

分层table:

Account ID Type ID Region ID TierNo Min Max Total A Total B
101 1 2 1 0 10000 .90 .10
101 1 2 2 10001 30000 .60 .40
101 1 2 3 30001 100000 .40 .60
101 1 2 4 100001 500000 .40 .60
101 1 2 5 500001 999999999999 .20 .80
102 1 3 1 0 7800 .80 .20
102 1 3 2 7801 12800 .70 .30
102 1 3 3 12801 34000 .60 .40
102 1 3 4 34001 50000 .50 .50
102 1 3 5 5000 1 999999999999 .50 .50
103 2 1 1 0 10000 .90 .10
103 2 1 2 10001 30000 .60 .40
103 2 1 3 30001 100000 .40 .60
103 2 1 4 100001 500000 .40 .60
103 2 1 5 500001 999999999999 .20 .80

当前table样本:

Trans ID Account ID Type ID Region ID GrossAmt Total A % Total A $ Net Amt
100001 101 1 2 42650
100002 102 1 3 42650
100003 103 2 1 42650

期望的输出:

Trans ID Account ID Type ID Region ID GrossAmt Total A % Total A $ Net Amt
100001 101 1 2 42650 0.611 26059.99 16589.99
100002 102 1 3 42650 0.628 26784.98 15864.99
100003 103 2 1 42650 0.40 17060.00 25590.00

我已经能够对之前的 post 进行一些编辑以获取帐户,但似乎无法弄清楚 TransID 100003 中分层查找值的逻辑。

理想情况下,我更愿意在 table 值函数(或两个)中创建此逻辑,然后将其合并到一个视图中,我将使用该视图使用 C# 在 Web 表单中进行报告。

SELECT
  c.*,
  [Total A %] = t.Total / c.GrossAmt,
  [Total A $] = t.Total,
  [Net Amt]   = c.GrossAmt - t.Total
FROM #temp c
INNER JOIN Accounts a ON a.[Account ID] = c.[Account ID]
CROSS APPLY (
    SELECT
      Total = SUM((v.ActualMax - t.[Min]) * t.[Total A %])
    FROM [dbo].[Tiered Table] t
    CROSS APPLY (VALUES(
      CASE WHEN c.GrossAmt < t.[Max] THEN c.GrossAmt ELSE t.[Max] END
    )) v(ActualMax)
    WHERE c.GrossAmt > t.[Min] AND t.[Account ID] = c.[Account ID]
) t;

任何想法或指导都将非常有帮助和感激。

这似乎是 AND OR 逻辑的简单问题。 您需要排除 TypeID = 2 并且还具有他们的最大值 低于 GrossAmt 的水平。

然后您只需有条件地汇总总金额(仅对于分层行,只有一行)或仅汇总该层的金额(对于累积层)。

SELECT
  c.*,
  [Total A %] = t.Total / c.GrossAmt,
  [Total A $] = t.Total,
  [Net Amt]   = c.GrossAmt - t.Total
FROM CurrentData c
INNER JOIN Accounts a ON a.[AccountID] = c.[AccountID]
CROSS APPLY (
    SELECT
      Total = SUM(CASE WHEN t.TypeID = 2 THEN v.GrossAmt ELSE (v.ActualMax - t.[Min]) END * t.[Total A])
    FROM [dbo].[Tiers] t
    CROSS APPLY (VALUES(
      CASE WHEN c.GrossAmt < t.[Max] THEN c.GrossAmt ELSE t.[Max] END,
      c.GrossAmt
    )) v(ActualMax, GrossAmt)
    WHERE t.[AccountID] = c.[AccountID]
      AND t.TypeID = c.TypeID
      AND t.RegionID = c.RegionID
      AND c.GrossAmt > t.[Min]
      AND (t.TypeID = 1 OR c.GrossAmt <= t.Max)
) t;

db<>fiddle

The second CROSS APPLY is only necessary because of aggregating outer values. You don't need this if you place it in a function, as shown in your previous question.

注意这里应该使用半开区间。换句话说,MinMax 应该是互斥的。否则可能会出现“漏网之鱼”的价值观。