繁体   English   中英

T-SQL如何计算来自另一个表和不确定行日期的金额

[英]T-SQL how to count amount of money from another table and Uncertain rows dates

我有一个像下面的表格,它有一个序列号,代码和日期

data table1

seqno       code  date
00009976    44  2010-05-04 00:00:00.000
00021577    4   2010-11-02 15:10:54.193
00021577    4   2011-03-16 16:58:35.880
00021577    44  2011-09-29 00:00:00.000
00003906    44  2012-06-25 00:00:00.000
00029266    3   2011-01-07 08:42:15.407
00029266    4   2011-08-08 15:47:33.337
00029266    44  2011-10-24 00:00:00.000
00012024    4   2011-03-01 09:28:09.790
00012024    44  2012-01-09 00:00:00.000
00006521    4   2011-12-28 08:55:23.567
00006521    44  2012-05-17 00:00:00.000
00071790    1   2011-09-02 09:23:33.000
00071790    44  2012-04-23 00:00:00.000
00008720    44  2012-04-03 00:00:00.000
00010872    3   2012-06-25 13:49:50.197
00010872    44  2012-09-11 00:00:00.000

还有另一张桌子

data table2
seqno      NUMBERS   getdate
00009976    504 2010-05-04 00:00:00.000
00009976    53470   NULL
00021577    10000   2010-12-17 00:00:00.000
00021577    5000    2011-01-18 00:00:00.000
00021577    2000    2011-03-16 00:00:00.000
00021577    5000    2011-04-13 00:00:00.000
00021577    3000    2011-04-13 00:00:00.000
00021577    4000    2011-06-15 00:00:00.000
00021577    2000    2011-05-19 00:00:00.000
00021577    3000    2011-05-26 00:00:00.000
00021577    5000    2011-05-26 00:00:00.000
00021577    1000    2011-05-26 00:00:00.000
00021577    5000    2011-05-26 00:00:00.000
00021577    4000    2011-09-07 00:00:00.000
00021577    11649   2011-09-29 00:00:00.000
00003906    38665   NULL
00029266    230 2011-05-06 00:00:00.000
00029266    265 2011-05-11 00:00:00.000
00029266    2400    2011-05-24 00:00:00.000
00029266    11528   2011-09-22 00:00:00.000
00029266    9379    2011-10-20 00:00:00.000
00029266    12310   2011-10-24 00:00:00.000
00012024    4124    2012-01-09 00:00:00.000
00012024    5600    2012-01-09 00:00:00.000
00012024    5600    2012-01-09 00:00:00.000
00012024    5600    2012-01-09 00:00:00.000
00012024    5600    2012-01-09 00:00:00.000
00012024    5600    2012-01-09 00:00:00.000
00012024    5600    2012-01-09 00:00:00.000
00012024    4972    2012-01-09 00:00:00.000
00006521    3611    2011-02-01 00:00:00.000
00006521    8647    2011-02-01 00:00:00.000
00006521    32413   2011-02-01 00:00:00.000
00006521    137 2012-05-17 00:00:00.000
00071790    50000   2011-10-28 00:00:00.000
00071790    100000  2012-04-23 00:00:00.000
00008720    61250   2012-04-03 00:00:00.000
00010872    19773   2012-07-31 00:00:00.000
00010872    46395   2012-09-11 00:00:00.000

现在我使用来自table1的seqno和date以及来自table2的总和,并通过代码将正确的字段更新为#resulttable,也许像

if code = '3'
begin
    update #resulttable
    set code3 = a.num
    from 
    (select sum(NUMBERS) num
    from #table2
    where seqno = "SEQNO" and getdate between "DATE1 from table1" and "DATE2 from table1"
    ) a
end
else if code = '4'
begin
    update #resulttable
    set code4 = a.num
    from 
    (select sum(NUMBERS) num
    from #table2 
    where seqno = "SEQNO" and getdate between "DATE1 from table1" and "DATE2 from table1"
    ) a
end

我不知道如何将每个seqno的date1和date2转换为sql语句,并且如果相同的seqno有两个以上的日期,我必须将date2和date3相加,并将date3和date4相加

现在我使用光标和GOTO来解决这个问题,但是它确实很慢,我的代码如下

declare @seqno char(8), @date1 datetime, @date2 datetime, @code1 char(2), @code2 char(2)
DECLARE user_cursor CURSOR FORWARD_ONLY FAST_FORWARD FOR select distinct SEQNO from #table11
OPEN user_cursor
FETCH NEXT FROM user_cursor INTO @seqno
while(@@FETCH_STATUS = 0)
begin
RERUN:
    select top 1 @date1 = exec_date, @code1 = code from #table1 where seqno = @seqno order by getdate
    delete #table1 where exec_year = seqno = @seqno and getdate = @date1
    select top 1 @date2 = exec_date, @code2 = code from #table1 where seqno = @seqno order by getdate
    if @code1 = '1'
    begin
        update #result_table
        set code1 = a.all_pay + ISNULL(code1,0)
        from #result_table t
            inner join
                (select seqno,sum(NUMBER) all_pay
                from #table2 m
                where (m_getdate between @date1 and @date2) 
                group by SEQNO
                ) a on a.SEQNO = t.seqno
        where t.seqno = @seqno
    end
    else if @code1 = '2'
    begin
        update #result_table
        set code2 = a.all_pay + ISNULL(code2,0)
        from #result_table t
            inner join
                (select seqno,sum(NUMBER) all_pay
                from #table2 m
                where (m_getdate between @date1 and @date2) 
                group by SEQNO
                ) a on a.SEQNO = t.seqno    
        where t.seqno = @seqno
    end
if @code2 <> '44'
    GOTO RERUN

FETCH NEXT FROM user_cursor INTO @seqno
end
CLOSE user_cursor 
DEALLOCATE user_cursor

没有游标,此代码可以重新编写为普通的t-sql代码吗?

结果应该是

seqno   code1   code2   code3   code4   code5   code6   code7   code8   code9
21577   NULL    NULL    NULL    60649   NULL    NULL    NULL    NULL    NULL
29266   NULL    NULL    2895    33217   NULL    NULL    NULL    NULL    NULL    
12024   NULL    NULL    NULL    42696   NULL    NULL    NULL    NULL    NULL    
6521    NULL    NULL    NULL    137 NULL    NULL    NULL    NULL    NULL    
71790   150000  NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    
8720    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    
10872   NULL    NULL    66168   NULL    NULL    NULL    NULL    NULL    NULL    

谢谢@ gordon-linoff给我很好的建议,现在我的代码就像

select dd.SEQNO,
SUM(case when code = '1' then numbers end) as code1,
SUM(case when code = '2' then numbers end) as code2,
SUM(case when code = '3' then numbers end) as code3,
SUM(case when code = '4' then numbers end) as code4,
SUM(case when code = '5' then numbers end) as code5,
SUM(case when code = '6' then numbers end) as code6,
SUM(case when code = '7' then numbers end) as code7,
SUM(case when code = '8' then numbers end) as code8,
SUM(case when code = '9' then numbers end) as code9
from #resulttable t
join
(select EXEC_YEAR,EXEC_CASE,EXEC_SEQNO,
    (select top 1 t.code
    from #table1 t
    where t.seqno = m.SEQNO and m.getdate < t.date
    ) as code, numbers
from #table2 m
) dd
on dd.SEQNO = t.seqno
group by dd.SEQNO

但是数字需要放在上一个日期的代码中,这可能吗?

您可以使用相关子查询从第一张表中获取第二张表中每一行的代码。 然后,您可以根据需要聚合和旋转它们:

select t.seqno,
       sum(case when thecode = 'code1' then numbers end) as code1,
       sum(case when thecode = 'code2' then numbers end) as code2,
       . . .
       sum(case when thecode = 'code9' then numbers end) as code9
from (select rt.*,
             (select top 1 code
              from #anothertable at
              where at.date <= rt.m_getdate and at.seqno = rt.seqno
              order by at.date desc
             ) as thecode
      from #resulttable rt
     ) t
group by t.seqno

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM