简体   繁体   English

SQL和会计年度数据检索

[英]SQL and Fiscal year data retrieval

I have an issue trying to retrieve fiscal data from my database. 我尝试从数据库中检索财务数据时遇到问题。 For example, the table I am using to calculate data between months has the month and the fy year (ie 1112 (Nov 2012)). 例如,我用来计算月份之间数据的表具有月份和年度(即1112(2012年11月))。 When I try to calculate the AMT Due data between the months Oct - Dec there is no data that is calculated. 当我尝试计算10月-12月之间的AMT到期数据时,没有计算出的数据。 However, when I calculate the data between Jan - Sept, it has no problem but fails to incorporate the data from the beginning of the fy(OCT NOV DEC) resulting with inaccurate data. 但是,当我计算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

I know the issue, I just can't seem to fix this problem. 我知道这个问题,但我似乎无法解决此问题。 I would love any ones input on this matter. 我很乐意就此事提供任何意见。

 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 

You could write a user-defined function to return Fiscal year for a given date... 您可以编写一个用户定义的函数以返回给定日期的会计年度...

    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

It's a pretty light-weight function, which you can now use in queries. 这是一个非常轻量级的函数,您现在可以在查询中使用它。

Here's an example: 这是一个例子:

 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)

IF m_y is already in your database, you can use that for your BETWEEN selection, as long as everything is in the same century. 如果m_y已经存在于数据库中,则可以将其用于BETWEEN选择,只要所有内容都在同一世纪即可。

You're relying on the BETWEEN operator, which might give you surprising results with columns that you might interpret as numbers, but which the dbms will interpret as char(n) or varchar(n). 你依靠BETWEEN操作,这可能给你, 可以解释为数字列令人惊讶的结果,但其DBMS会将其解释为char(n)或VARCHAR(n)的。 This is especially true with incomplete dates. 日期不完整的情况尤其如此。

The simplest approach is to avoid calculating altogether, and just name the months you want in the WHERE clause. 最简单的方法是避免完全计算,而只需在WHERE子句中命名所需的月份。 Defensive programming would name the fiscal year, too. 防御性编程也将指定会计年度。

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

A better approach is to fix your storage in a way that preserves useful (and sensible) semantics. 更好的方法是以保留有用(且明智的)语义的方式修复存储。 Here are two different ways to store fiscal periods, "month first" and "year first". 这是两种不同的存储财务期间的方式,“月初”和“年初”。

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');

Now try a simple query, month first. 现在,从一个月开始尝试一个简单的查询。

-- 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.

The same query, year first. 相同的查询,第一年。

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

y_m 
--
1210
1211
1212
1301
1302

Better still, avoid Y2K issues and store the year as four digits: 201201, 201302, etc. 更好的是,避免Y2K问题并将年份存储为四位数:201201、201302等。

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

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