我有这个表,只有两列,每个记录存储给定月份的利率:
id rate
===========
199502 3.63
199503 2.60
199504 4.26
199505 4.25
... ...
201704 0.79
201705 0.93
201706 0.81
201707 0.80
201708 0.14
根据这个比率,我需要创建另一个累积费率表,其结构类似,其数据按YYYYMM(月/年)参数的函数计算,这种方式(此公式在法律上是强制性的):
在给定参数201708
的情况下,我将通过此示例澄清此规则:
SOURCE CALCULATED
id rate id rate
=========== =============
199502 3.63 199502 360.97 (1 + sum(rate(199503) to rate(201707)))
199503 2.60 199503 358.37 (1 + sum(rate(199504) to rate(201707)))
199504 4.26 199504 354.11 (1 + sum(rate(199505) to rate(201707)))
199505 4.25 199505 349.86 (1 + sum(rate(199506) to rate(201707)))
... ... ... ...
201704 0.79 201704 3.54 (1 + rate(201705) + rate(201706) + rate(201707))
201705 0.93 201705 2.61 (1 + rate(201706) + rate(201707))
201706 0.81 201706 1.80 (1 + rate(201707))
201707 0.80 201707 1.00 (per definition)
201708 0.14 201708 0.00 (per definition)
现在我已经实现了一个VB.NET函数,它读取源表并生成计算表,但这是在运行时在每台客户机上完成的:
Public Function AccumRates(targetDate As Date) As DataTable
Dim dtTarget = Rates.Clone
Dim targetId = targetDate.ToString("yyyyMM")
Dim targetIdAnt = targetDate.AddMonths(-1).ToString("yyyyMM")
For Each dr In Rates.Select("id<=" & targetId & " and id>199412")
If dr("id") = targetId Then
dtTarget.Rows.Add(dr("id"), 0)
ElseIf dr("id") = targetIdAnt Then
dtTarget.Rows.Add(dr("id"), 1)
Else
Dim intermediates =
Rates.Select("id>" & dr("id") & " and id<" & targetId).Select(
Function(ldr) New With {
.id = ldr.Field(Of Integer)("id"),
.rate = ldr.Field(Of Decimal)("rate")}
).ToArray
dtTarget.Rows.Add(
dr("id"),
1 + intermediates.Sum(
Function(i) i.rate))
End If
Next
Return dtTarget
End Function
我的问题是如何将此作为查询放在我的数据库中,以便其他查询可以动态使用它,这些查询将使用这些累计费率将债务更新到任何给定日期。
非常感谢!
修改
我设法创建了一个返回我想要的数据的查询,现在我只是不知道如何封装它,以便可以从另一个查询中调用它来传递任何id
作为参数(这里我是用SET ...
语句做的:
SET @targetId=201708;
SELECT
id AS id_acum,
COALESCE(1 + (SELECT
SUM(taxa)
FROM
tableSelic AS ts
WHERE
id > id_acum AND id < @targetId
LIMIT 1),
IF(id >= @targetId, 0, 1)) AS acum
FROM
tableSelic
WHERE id>199412;
那是因为我对MySQL很陌生,我已经习惯了MS-Access,其中参数化查询非常容易创建。
答案 0 :(得分:1)
例如:
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id INT NOT NULL PRIMARY KEY
,rate DECIMAL(5,2) NOT NULL
);
INSERT INTO my_table VALUES
(201704,0.79),
(201705,0.93),
(201706,0.81),
(201707,0.80),
(201708,0.14);
SELECT *
, CASE WHEN @flag IS NULL THEN @i:=1 ELSE @i:=@i+rate END i
, @flag:=1 flag
FROM my_table
, (SELECT @flag:=null,@i:=0) vars
ORDER
BY id DESC;
+--------+------+-------------+-------+------+------+
| id | rate | @flag:=null | @i:=0 | i | flag |
+--------+------+-------------+-------+------+------+
| 201708 | 0.14 | NULL | 0 | 1 | 1 |
| 201707 | 0.80 | NULL | 0 | 1.80 | 1 |
| 201706 | 0.81 | NULL | 0 | 2.61 | 1 |
| 201705 | 0.93 | NULL | 0 | 3.54 | 1 |
| 201704 | 0.79 | NULL | 0 | 4.33 | 1 |
+--------+------+-------------+-------+------+------+
5 rows in set (0.00 sec)
答案 1 :(得分:0)
好的,我使用了一个函数:
CREATE FUNCTION `AccumulatedRates`(start_id integer, target_id integer) RETURNS decimal(6,2)
BEGIN
DECLARE select_var decimal(6,2);
SET select_var = (
SELECT COALESCE(1 + (
SELECT SUM(rate)
FROM tableRates
WHERE id > start_id AND id < target_id LIMIT 1
), IF(id >= unto, 0, 1)) AS acum
FROM tableRates
WHERE id=start_id);
RETURN select_var;
END
他们是一个简单的查询:
SELECT *, AccumulatedRates(id,@present_id) as acum FROM tableRates;
其中@present_id
作为参数传递。
感谢所有人,无论如何!