使用mysql运行总计

时间:2018-05-03 15:58:18

标签: php sql html5

(如果我对投资组合进行硬编码,请参阅下面的工作系统参考查询和结果更新) 我试图使用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    

1 个答案:

答案 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;