(如果我对投资组合进行硬编码,请参阅下面的工作系统参考查询和结果更新) 我试图使用mysql(使用子选择和使用变量)以两种方式之一创建一个运行总额的付款余额,但这两种方法都没有产生正确的结果。第一种方法是最接近的,只有在日期相同的情况下失败,尽管这种方法的效率低于使用变量。
该报告显示按付款日期(pdate)顺序排列的股票组合的股息支付,按付款日期,投资组合和股份(代码)分组
SELECT
d.code AS code,
p.name AS portfolio,
d.pdate AS pdate,
d.dividend AS dividend,
CEILING(SUM(t.quantity)) AS quantity,
CEILING(SUM(t.quantity) * d.dividend / 100) AS payment,
(
SELECT CEILING(SUM(din.dividend * tin.quantity) / 100)
FROM
transaction tin
INNER JOIN member min ON (tin.member_id = min.id)
INNER JOIN dividend din ON (tin.code = din.code)
INNER JOIN portfolio pin ON (tin.portfolio_id = pin.id)
WHERE
(min.id >= '01' AND min.id <= '02')
AND
din.pdate <= d.pdate
AND
din.pdate >= NOW()
AND
pin.name <> 'FDR_JNT'
) AS balance
FROM
transaction t
INNER JOIN member m ON (m.id = t.member_id)
INNER JOIN portfolio p ON (p.id = t.portfolio_id)
INNER JOIN account a ON (a.id = p.account_id)
INNER JOIN dividend d ON (d.code = t.code)
WHERE
(m.id >= '01' AND m.id <= '02')
AND
d.exchange = t.exchange
AND
d.pdate >= NOW()
GROUP BY pdate, portfolio, code
结果显示如下,RHS平衡
+----------+---------------+--------------+---------------+--------------+-------------+----------+
| code | portfolio | pdate | dividend | quantity | payment | balance |
+----------+---------------+--------------+---------------+--------------+-------------+----------+
| BLND | AJB_SIPP_CO | 2018-05-05 | 7.52 | 1643 | 124 | 124 |
| AV. | AJB_SIPP_CO | 2018-05-17 | 15.88 | 2135 | 340 | 831 |
| AV. | SFT_DEA_CO | 2018-05-17 | 15.88 | 2318 | 369 | 831 |
| DLG | AJB_SIPP_CO | 2018-05-18 | 9.7 | 2732 | 266 | 1367 |
| DLG | SFT_DEA_CO | 2018-05-18 | 9.7 | 2789 | 271 | 1367 |
| SLA | AJB_SIPP_CO | 2018-05-23 | 13.35 | 2820 | 377 | 2177 |
| SLA | SFT_DEA_CO | 2018-05-23 | 13.35 | 3247 | 434 | 2177 |
| PHP | AJB_SIPP_CO | 2018-05-27 | 1.31 | 6947 | 92 | 2268 |
| LLOY | AJB_SIPP_CO | 2018-05-29 | 2.05 | 15519 | 319 | 3569 |
| LLOY | SFT_DEA_CL | 2018-05-29 | 2.05 | 40011 | 821 | 3569 |
| LLOY | SFT_ISA_CO | 2018-05-29 | 2.05 | 7973 | 164 | 3569 |
| FCPT | AJB_SIPP_CL | 2018-05-31 | 0.5 | 223 | 2 | 3809 |
+----------+---------------+--------------+---------------+--------------+-------------+----------+
我还尝试使用第二种方法,如下所示
SELECT
d.code AS code,
p.name AS portfolio,
d.pdate AS pdate,
d.dividend AS dividend,
CEILING(SUM(t.quantity)) AS quantity,
CEILING(SUM(t.quantity) * d.dividend / 100) AS payment,
(@running_total := @running_total + CEILING(SUM(t.quantity) * d.dividend / 100)) AS balance
FROM
transaction t
JOIN (SELECT @running_total := 0) r
INNER JOIN member m ON (m.id = t.member_id)
INNER JOIN portfolio p ON (p.id = t.portfolio_id)
INNER JOIN account a ON (a.id = p.account_id)
INNER JOIN dividend d ON (d.code = t.code)
WHERE
(m.id >= '01' AND m.id <= '02')
AND
d.exchange = t.exchange
AND
d.pdate >= NOW()
GROUP BY
pdate, portfolio, code
此处的结果
+----------+--------------+--------------+-------------+--------------+-------------+-------------------+
| code | portfolio | pdate | dividend | quantity | payment | balance |
+----------+--------------+--------------+-------------+--------------+-------------+-------------------+
| BLND | AJB_SIPP_CO | 2018-05-05 | 7.52 | 1643 | 124 | 124 |
| AV. | AJB_SIPP_CO | 2018-05-17 | 15.88 | 2135 | 340 | 340 |
| AV. | SFT_DEA_CO | 2018-05-17 | 15.88 | 2318 | 369 | 369 |
| DLG | AJB_SIPP_CO | 2018-05-18 | 9.7 | 2732 | 266 | 266 |
| DLG | SFT_DEA_CO | 2018-05-18 | 9.7 | 2789 | 271 | 271 |
| SLA | AJB_SIPP_CO | 2018-05-23 | 13.35 | 2820 | 377 | 377 |
| SLA | SFT_DEA_CO | 2018-05-23 | 13.35 | 3247 | 434 | 434 |
| PHP | AJB_SIPP_CO | 2018-05-27 | 1.31 | 6947 | 92 | 92 |
| LLOY | AJB_SIPP_CO | 2018-05-29 | 2.05 | 15519 | 319 | 319 |
| LLOY | SFT_DEA_CL | 2018-05-29 | 2.05 | 40011 | +----------+--------------+--------------+-------------+--------------+-------------+-------------------+
同样,这不会产生预期的结果
问题似乎与在同一日期有多次付款的时间有关,如果我对所有值&lt; =行日期进行分组,如果我有一个唯一字段或顺序计数,以避免重复键(日期,投资组合,代码)
我对此报告的任何帮助都非常感激,因为我曾尝试对此报告进行编码而不会成功。
如果您需要更多信息,请与我们联系。
非常感谢提前
科林
如果我对投资组合进行硬编码 SFT_DEA_CO ,则会更新,累计余额如下所示
SELECT
d.code AS code,
p.name AS portfolio,
d.pdate AS pdate,
d.dividend AS dividend,
CEILING(SUM(t.quantity)) AS quantity,
CEILING(SUM(t.quantity) * d.dividend / 100) AS payment,
(
SELECT
CEILING(SUM(din.dividend * tin.quantity)/100)
FROM
transaction tin
INNER JOIN member min ON (tin.member_id = min.id)
INNER JOIN dividend din ON (tin.code = din.code)
INNER JOIN portfolio pin ON (tin.portfolio_id = pin.id)
WHERE
(min.id >= '01' AND min.id <= '02')
AND
din.pdate <= d.pdate
AND
din.pdate >= NOW()
AND
pin.name = 'SFT_DEA_CO'
)
AS balance
FROM
transaction t
INNER JOIN member m ON (m.id = t.member_id)
INNER JOIN portfolio p ON (p.id = t.portfolio_id)
INNER JOIN account a ON (a.id = p.account_id)
INNER JOIN dividend d ON (d.code = t.code)
WHERE
(m.id >= '01' AND m.id <= '02')
AND
d.exchange = t.exchange
AND
d.pdate >= NOW()
AND
p.name = 'SFT_DEA_CO'
GROUP BY
pdate, portfolio, code
结果显示如下,其中累积起作用,仅当投资组合是硬编码时
code portfolio pdate dividend quantity payment balance
AV. SFT_DEA_CO 2018-05-17 15.88 2318 369 369
DLG SFT_DEA_CO 2018-05-18 9.7 2789 271 639
SLA SFT_DEA_CO 2018-05-23 13.35 3247 434 1073
BP. SFT_DEA_CO 2018-06-23 7.67 446 35 1107
VUKE SFT_DEA_CO 2018-07-05 44.255 899 398 1505
GSK SFT_DEA_CO 2018-07-13 19 2242 426 1931
MKS SFT_DEA_CO 2018-07-14 11.9 4223 503 2433
VOD SFT_DEA_CO 2018-08-04 8.8 12053 1061 3494
BT.A SFT_DEA_CO 2018-09-04 10.55 8802 929 4422
DLG SFT_DEA_CO 2018-09-08 6.8 2789 190 4612
BP. SFT_DEA_CO 2018-09-22 7.67 446 35 5386
SSE SFT_DEA_CO 2018-09-22 63.9 1158 740 5386
VUKE SFT_DEA_CO 2018-10-04 36.046 899 325 5710
GSK SFT_DEA_CO 2018-10-12 19 2242 426 6136
答案 0 :(得分:0)
也许这个例子会给你必要的结构...... 我构建了一个名为“test”的表,其中包含您引用的几个列。查询示例有2个单独的行标识变量,因此您可以确认行的处理顺序。
内部子查询具有row_num计数器,该计数器记录聚合过程中行走的顺序,外部查询具有row_n计数器,该计数器记录您尝试用于显示数据的新订单。
希望这有帮助。
查询如下......
select @row_n := @row_n + 1 as row_n, row_num, code, portfolio, pdate, dividend, quantity, payment, balance from ( select @row_num := @row_num + 1 as row_num, code, portfolio, pdate, dividend, quantity, ceiling(dividend*quantity/100) as payment, @balance := ceiling(dividend*quantity/100) + if (@prev_pfl = portfolio,@balance,0) as balance, @prev_pfl := portfolio as prev_portfolio from test cross join ( select @row_num := 0, @balance := 0, @prev_pfl := '' ) as InitVarsAlias order by portfolio, pdate,code) as SubQueryAlias cross join (select @row_n := 0 ) as InitVarsAlias2 order by pdate,portfolio,code,row_num;
,结果在
之下row_n row_num code portfolio pdate dividend quantity payment balance 1 2 BLND AJB_SIPP_CO 2018-05-05 7.52 1643 124 124 2 3 BLND AJB_SIPP_CO 2018-05-05 7.52 1643 124 248 3 4 AV. AJB_SIPP_CO 2018-05-17 15.88 2135 340 588 4 18 AV. SFT_DEA_CO 2018-05-17 15.88 2318 369 369 5 5 DLG AJB_SIPP_CO 2018-05-18 9.70 2732 266 854 6 19 DLG SFT_DEA_CO 2018-05-18 9.70 2789 271 640 7 6 SLA AJB_SIPP_CO 2018-05-23 13.35 2820 377 1231 8 20 SLA SFT_DEA_CO 2018-05-23 13.35 3247 434 1074 9 7 PHP AJB_SIPP_CO 2018-05-27 1.31 6947 92 1323 10 8 LLOY AJB_SIPP_CO 2018-05-29 2.05 15519 319 1642 11 15 LLOY SFT_DEA_CL 2018-05-29 2.05 40011 821 821 12 24 LLOY SFT_ISA_CO 2018-05-29 2.05 7973 164 164 13 1 FCPT AJB_SIPP_CL 2018-05-31 0.50 223 2 2 14 9 FCPT AJB_SIPP_CO 2018-05-31 0.50 5837 30 1672 15 10 RLSEB AJB_SIPP_CO 2018-05-31 1.80 5021 91 1763 16 22 FCPT SFT_ISA_CL 2018-05-31 0.50 3609 19 19 17 23 RLSEB SFT_ISA_CL 2018-05-31 1.80 2100 38 57 18 25 FCPT SFT_ISA_CO 2018-05-31 0.50 5136 26 190 19 26 RLSEB SFT_ISA_CO 2018-05-31 1.80 2100 38 228 20 11 LGEN AJB_SIPP_CO 2018-06-08 10.35 3923 407 2170 21 16 LGEN SFT_DEA_CL 2018-06-08 10.35 10652 1103 1924 22 12 BP. AJB_SIPP_CO 2018-06-23 7.67 2130 164 2334 23 13 RDSB AJB_SIPP_CO 2018-06-23 35.02 436 153 2487 24 17 RDSB SFT_DEA_CL 2018-06-23 35.02 1292 453 2377 25 21 BP. SFT_DEA_CO 2018-06-23 7.67 446 35 1109 26 14 CNA AJB_SIPP_CO 2018-06-29 8.40 7512 632 3119
如果你想在这里重新创建我的测试,那就是我在测试中使用的表模式。
CREATE TABLE `test` ( `code` varchar(10) DEFAULT NULL, `portfolio` varchar(30) DEFAULT NULL, `pdate` date DEFAULT NULL, `dividend` decimal(12,2) DEFAULT NULL, `quantity` int(11) DEFAULT NULL, `payment` double(12,2) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
以下是填充它的代码......
LOCK TABLES `test` WRITE; /*!40000 ALTER TABLE `test` DISABLE KEYS */; INSERT INTO `test` VALUES ('BLND','AJB_SIPP_CO','2018-05-05',7.52,1643,124.00), ('BLND','AJB_SIPP_CO','2018-05-05',7.52,1643,124.00), ('AV.','AJB_SIPP_CO','2018-05-17',15.88,2135,340.00), ('AV.','SFT_DEA_CO','2018-05-17',15.88,2318,369.00), ('DLG','AJB_SIPP_CO','2018-05-18',9.70,2732,266.00), ('DLG','SFT_DEA_CO','2018-05-18',9.70,2789,271.00), ('SLA','AJB_SIPP_CO','2018-05-23',13.35,2820,377.00), ('SLA','SFT_DEA_CO','2018-05-23',13.35,3247,434.00), ('PHP','AJB_SIPP_CO','2018-05-27',1.31,6947,92.00), ('LLOY','AJB_SIPP_CO','2018-05-29',2.05,15519,319.00), ('LLOY','SFT_DEA_CL','2018-05-29',2.05,40011,821.00), ('LLOY','SFT_ISA_CO','2018-05-29',2.05,7973,164.00), ('FCPT','AJB_SIPP_CL','2018-05-31',0.50,223,2.00), ('FCPT','AJB_SIPP_CO','2018-05-31',0.50,5837,30.00), ('RLSEB','AJB_SIPP_CO','2018-05-31',1.80,5021,91.00), ('FCPT','SFT_ISA_CL','2018-05-31',0.50,3609,19.00), ('RLSEB','SFT_ISA_CL','2018-05-31',1.80,2100,38.00), ('FCPT','SFT_ISA_CO','2018-05-31',0.50,5136,26.00), ('RLSEB','SFT_ISA_CO','2018-05-31',1.80,2100,38.00), ('LGEN','AJB_SIPP_CO','2018-06-08',10.35,3923,407.00), ('LGEN','SFT_DEA_CL','2018-06-08',10.35,10652,1103.00), ('BP.','AJB_SIPP_CO','2018-06-23',7.67,2130,164.00), ('RDSB','AJB_SIPP_CO','2018-06-23',35.02,436,153.00), ('RDSB','SFT_DEA_CL','2018-06-23',35.02,1292,453.00), ('BP.','SFT_DEA_CO','2018-06-23',7.67,446,35.00), ('CNA','AJB_SIPP_CO','2018-06-29',8.40,7512,632.00); /*!40000 ALTER TABLE `test` ENABLE KEYS */; UNLOCK TABLES;
然后只需运行开头列出的查询。
- 完成 -
基于上面的示例,我认为您的查询将更接近于以下内容。
注意:我在结果中包含了内部查询row_num字段,但它不是必需的。
SELECT @row_n := @row_n + 1 as row_n, row_num, code, portfolio, pdate, dividend, quantity, payment, balance from ( SELECT @row_num := @row_num + 1 as row_num, din.code as code, pin.name as portfolio, din.pdate as pdate, din.dividend as dividend ceiling(sum(tin.quantity)) as quantity, ceiling(sum(din.dividend * tin.quantity)/100) as payment, ceiling(sum(din.dividend * tin.quantity)/100) + if(@prev_pfl = pin.name,@balance,0) as balance, @prev_pfl := pin.name FROM transaction tin INNER JOIN member min ON (tin.member_id = min.id) INNER JOIN dividend din ON (tin.code = din.code) INNER JOIN portfolio pin ON (tin.portfolio_id = pin.id) cross join ( select @row_num := 0, @balance := 0, @prev_pfl := '' ) as InitVarsAlias WHERE (min.id >= '01' AND min.id = NOW() ORDER BY pin.name,din.pdate,din.code ) AS SubQueryAlias cross join (select @row_n := 0 ) as InitVarsAlias2 order by pdate,portfolio,code,row_num;