【问题标题】:SQL - Aggregation between two string rowsSQL - 两个字符串行之间的聚合
【发布时间】:2019-03-01 10:30:31
【问题描述】:

我有一张下表,其中有员工的交易,其中工资代码为“S”:

Id | Code | Amount  | Date
1  | B    | 40      | 2017-01-01
1  | S    | 45000   | 2017-01-02
1  | D    | 30000   | 2017-01-15
1  | B    | 15000   | 2017-01-20
1  | S    | 45000   | 2017-02-02
1  | B    | -20000  | 2017-02-04
1  | B    | -10000  | 2017-02-05

我的目标是查看员工需要多少天才能耗尽所有工资

这是我想要的输出:

Id | Code | Amount | Month | # days when all salary drains
1  | S    | 45000  | 01    | 20
1  | S    | 45000  | 01    | 0

我已关注this 并尝试了以下 SQL 查询:

with cte as
     (
       select *,
        --CASE WHEN Transaction_Code in ('521', '522') then Transaction_Amt else null end as Last_V_ID
          -- find the latest 'V' ID per ArtNo
          max(case when Transaction_Code in ('521', '522') then Transaction_Amt end) 
          over (partition by INTERNAL_ACCT_NUM order by value_date) as Last_V_ID
       from [10.16.42.25].[Cross_Sell_PL].[dbo].[PL_NONPL_TRANS]
    WHERE INTERNAL_ACCT_NUM = '0103PBS8T6001'
    --order by value_date
     )
    select *,
     case when Transaction_Code in ('521', '522') then Transaction_Amt else
      ( lag(Last_V_ID,1,0) OVER (PARTITION BY INTERNAL_ACCT_NUM ORDER BY VALUE_DATE) ) 
      + Transaction_Amt end as running_balance,

       sum(case when Transaction_Amt < Last_V_ID then null else Transaction_Amt end)
       over (partition by INTERNAL_ACCT_NUM order by VALUE_DATE rows unbounded preceding)
    from cte
    order by Internal_Acct_num, value_date

问题是我无法限制代码之间的计算,也无法计算天数。

【问题讨论】:

  • 日期计算的逻辑是什么
  • 我已经编辑了代码
  • @user1584253 。 . .不知怎的,我怀疑代码和你要做什么有关,但是数据没有描述,计算不清楚。
  • 您的代码似乎与问题无关。它使用Transaction_Code,这在您上面引用的示例中没有。您想要的输出也是错误的。第二行似乎与第二个月有关,但是,您将其列为 01 月。第二行的天数是因为工资还没有用完吗?最后,我希望这是某种家庭作业,因为如果您深入了解员工的消费模式,我肯定不想为您工作 ;-)

标签: sql sql-server cumulative-sum


【解决方案1】:

根据您的反馈修改了我的答案。

该查询现在使用一个公用表表达式为工资金额和每月支付日期构建一个派生表,然后是另一个派生表,该表编译每个日历月汇总的所有交易的列表。

每月交易的总和与工资金额进行比较,只有当金额超过工资阈值时才会显示总天数(包括 +1,因为这包括作为第 1 天支付工资的日期)。

这样的查询显示 3 行,因为提供的示例数据包括 12 月的工资月份,但是没有与 12 月相比的工资金额,因此额外的 0。我希望这会有所帮助。

declare @employee_transaction table (
    Id int,
    Code nvarchar(1),
    Amount int,
    Date Date
);

insert into @employee_transaction (id, Code, Amount, Date)
values
(1  , 'B'    , 40      , '2017-01-01'),
(1  , 'S'    , 45000   , '2017-01-02'),
(1  , 'D'    , 30000   , '2017-01-15'),
(1  , 'B'    , 15000   , '2017-01-20'),
(1  , 'S'    , 45000   , '2017-02-02'),
(1  , 'B'    , -20000  , '2017-02-04'),
(1  , 'B'    , -10000  , '2017-02-05');


with Salaries as (Select INTERNAL_ACCT_NUM, Transaction_Code, Value_Date, 
Transaction_Amt as Salary_Per_Month from #test1 e where 
Transaction_Code='S'), 
Deductions as (select sum(case when Transaction_Amt<0 then Transaction_Amt 
else 0 end) as Amount, Max(Value_Date) as Drain_date from #TEST1 e2 
where Transaction_Code <>'S' and Value_Date>(select Value_Date from #TEST1 
e3 where Transaction_Code='S' and 
DATEPART(month,e2.Value_Date)=DATEPART(month,e3.Value_Date) 
and e3.Internal_Acct_Num=e2.Internal_Acct_Num) 
group by DATEPART(month,e2.Value_Date)) 

select distinct s.INTERNAL_ACCT_NUM, s.Transaction_Code, s.Salary_Per_Month, 
DATEPART(Month,e.Value_Date) as Month, 
coalesce(DATEDIFF(Day,S.Value_Date,(select d.Drain_Date from Deductions d 
where d.Amount+S.Salary_Per_Month<=0 and 
DatePart(month,d.Drain_Date)=DatePart(month,e.Value_Date) and 
d.drain_date>=s.value_date))+1,0) 
from #TEST1 e 
inner join Salaries s on e.Transaction_Code=s.Transaction_Code 
and e.INTERNAL_ACCT_NUM=s.INTERNAL_ACCT_NUM and s.Value_Date>=e.Value_Date 
and DATEPART(month, s.Value_Date)=DATEPART(month, e.Value_Date) 
order by Month;

【讨论】:

  • S、B 和 D 是交易代码。 S指工资。我的目标是看看客户需要多少才能耗尽他的薪水。如果提款金额等于或高于工资金额,则计算天数,但如果提款金额小于下一次工资之前的工资,则显示0天
  • 在扣除cte中,它给出的错误子查询返回超过1个值
  • 我已经编辑了扣除 cte 以现在包括 id,如果员工每月支付超过一次,那么这可能会导致问题,否则它应该可以正常工作。
  • 问题仍然存在
猜你喜欢
  • 2016-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-25
  • 1970-01-01
  • 2020-11-13
  • 2011-06-22
  • 2020-11-05
相关资源
最近更新 更多