我在尝试从数据库中检索财务数据时遇到问题。 例如,我用来计算月份之间的数据的表具有月份和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
答案 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等。