SQL和会计年度数据检索

时间:2013-07-08 15:42:35

标签: sql sql-server-2008 data-retrieval

我在尝试从数据库中检索财务数据时遇到问题。 例如,我用来计算月份之间的数据的表具有月份和fy年份(即1112(2012年11月))。当我尝试计算10月到12月之间的AMT到期数据时,没有计算数据。但是,当我在1月至9月之间计算数据时,它没有问题但是未能合并来自fy(OCT NOV DEC)开头的数据,导致数据不准确。

M_Y       Amt Due   dept    FY
1112      362.44     D2     2013
1212      10.50      D4     2013
0213      55.55      D1     2013

@LF = CAST((CAST@Current_FY_IN AS INT)-1) AS CHAR)
@startdate = @LFy + '10'
@enddate = CASE SUBSTRING(@mon_IN,1,1) WHEN '1' THEN @LY+@mon_IN ELSE @Current_FY_IN+@month_IN
@Current_FY_IN  (i.e. 2013) 
END

我知道这个问题,我似乎无法解决这个问题。我很想知道有关此事的任何意见。

 SELECT M_Y, ISNULL(SUM(Amt Due),0) AS AmtDueNow 
      FROM FYAmmountDue 
      WHERE
'20' + RIGHT(M_F,2) + LEFT(M_F,2) BETWEEN @startdate AND @enddate - 1 
 AND FY = @Current_FY_IN 

2 个答案:

答案 0 :(得分:1)

您可以编写用户定义的函数来返回给定日期的会计年度...

    CREATE FUNCTION dbo.fFiscalYear(@calendarDt DateTime)
      RETURNS Int
    (
        DECLARE @year Int
        SET @year = YEAR(@calendarDt)
        IF MONTH(@calendarDt) NOT IN (10, 11, 12)
           SET @year = @year - 1
        RETURN @year
    )
    GO

GRANT EXECUTE ON dbo.fFiscalYear TO  PUBLIC
GO

这是一个非常轻量级的功能,您现在可以在查询中使用它。

以下是一个例子:

 SELECT CONVERT(varchar(4), trans_dt, 12) AS m_y
        COALESCE(SUM(amt_due), 0) AS amt_due_now,
        dbo.fFiscalYear(trans_dt) AS fiscal_year
   FROM TransactionTable
        GROUP BY CONVERT(varchar(4), trans_dt, 12), dbo.fFiscalYear(trans_dt) 
        ORDER BY dbo.fFiscalYear(trans_dt), CONVERT(varchar(4), trans_dt, 12)

如果m_y已经存在于您的数据库中,只要所有内容都在同一个世纪,您就可以将其用于BETWEEN选择。

答案 1 :(得分:0)

您依赖于BETWEEN运算符,这可能会给您带来令人惊讶的结果,其中可能会将其解释为数字,但dbms将其解释为char(n)或varchar(n) 。对于不完整的日期,尤其如此。

最简单的方法是避免完全计算,只需在WHERE子句中命名所需的月份。防御性节目也将命名财政年度。

WHERE M_Y IN ('1012', '1112', '1212') 
  AND FY = 2013

更好的方法是以保留有用(和合理)语义的方式修复存储。以下是存储财政期间的两种不同方式,“月份优先”和“年度优先”。

drop table fiscal_periods;
create table fiscal_periods (
  y_m char(4) not null unique,
  m_y char(4) not null unique
);

insert into fiscal_periods values ('1201', '0112');
insert into fiscal_periods values ('1202', '0212');
insert into fiscal_periods values ('1203', '0312');
insert into fiscal_periods values ('1204', '0412');
insert into fiscal_periods values ('1205', '0512');
insert into fiscal_periods values ('1206', '0612');
insert into fiscal_periods values ('1207', '0712');
insert into fiscal_periods values ('1208', '0812');
insert into fiscal_periods values ('1209', '0912');
insert into fiscal_periods values ('1210', '1012');
insert into fiscal_periods values ('1211', '1112');
insert into fiscal_periods values ('1212', '1212');
insert into fiscal_periods values ('1301', '0113');
insert into fiscal_periods values ('1302', '0213');
insert into fiscal_periods values ('1303', '0313');
insert into fiscal_periods values ('1304', '0413');
insert into fiscal_periods values ('1305', '0513');
insert into fiscal_periods values ('1306', '0613');
insert into fiscal_periods values ('1307', '0713');
insert into fiscal_periods values ('1308', '0813');
insert into fiscal_periods values ('1309', '0913');
insert into fiscal_periods values ('1310', '1013');
insert into fiscal_periods values ('1311', '1113');
insert into fiscal_periods values ('1312', '1213');

现在首先尝试一个简单的查询。

-- Select the periods between Oct 2012 and Feb 2013
select m_y
from fiscal_periods
where m_y between '1012' and '0213'
order by m_y;
-- Returns the empty set.

相同的查询,第一年。

select y_m
from fiscal_periods
where y_m between '1210' and '1302'
order by y_m;

y_m 
--
1210
1211
1212
1301
1302

更好的是,避免Y2K问题并将年份存储为四位数:201201,201302等。

相关问题