转置上个月的数据

时间:2017-09-08 19:22:48

标签: sql postgresql

我有一个产生以下输出的查询:

Account ID  User Name   IRA Account Number  Statement Date  Ending Balance
123456789   John Smith  123 11/30/16     $249,800.00 
123456789   John Smith  123 12/31/16     $250,617.31 
123456789   John Smith  123 1/31/17  $253,016.75  
789123456   Cate Jones  789 4/30/17  $15,000.00 
789123456   Cate Jones  789 5/31/17  $15,045.23 
789123456   Cate Jones  789 6/30/17  $15,144.66 

但我需要在报告中添加Begin DateStarting Balance,分别是指定帐户ID的声明日期和上个月的期末余额,如下所示:

Account ID  User Name   IRA Account Number  Begin Date  Starting Balance    End Date    Ending Balance
123456789   John Smith  123 11/30/16     $249,800.00    12/31/16     $250,617.31 
123456789   John Smith  123 12/31/16     $250,617.31    1/31/17  $253,016.75 
789123456   Cate Jones  789 4/30/17  $15,000.00     5/31/17  $15,045.23 
789123456   Cate Jones  789 5/31/17  $15,045.23     6/30/17  $15,144.66 

我可以使用date_trunc('month', statement_date - interval '1' month)获取上个月的数据,但我不清楚如何转置数据。这是我的尝试

WITH customer_details AS
(
    SELECT a.id                           AS account_id,
      a.ps_id                             AS account_ps_id,
      u.first_name || ' ' || u.last_name AS user_name,
      i.account_number                   AS ira_account_number
  FROM retail.accounts a
    INNER JOIN retail.iras i ON a.owner_type = 'Ira' AND a.owner_id = i.id
    INNER JOIN retail.users u ON a.user_id = u.id
),
  account_balances_previous AS
(
  SELECT account_id,
         date_trunc('month', entered_at - interval '1' month)::date AS statement_begin_date,
         COALESCE(SUM(amount) FILTER (WHERE credit_account = 'client_deposit'),0) -COALESCE(SUM(amount) FILTER (WHERE debit_account = 'client_deposit'),0) AS cash,
         COALESCE(SUM(amount) FILTER (WHERE credit_account = 'client_committed_security'),0) -COALESCE(SUM(amount) FILTER (WHERE debit_account = 'client_committed_security'),0) AS committed,
         COALESCE(SUM(amount) FILTER (WHERE credit_account = 'client_funded_security'),0) -COALESCE(SUM(amount) FILTER (WHERE debit_account = 'client_funded_security'),0) AS funded
  FROM
    retail.accounting_entries
  GROUP BY account_id,entered_at
),
account_balances_current AS
(
  SELECT account_id,
         date_trunc('month', entered_at)::date AS statement_end_date,
         COALESCE(SUM(amount) FILTER (WHERE credit_account = 'client_deposit'),0) -COALESCE(SUM(amount) FILTER (WHERE debit_account = 'client_deposit'),0) AS cash,
         COALESCE(SUM(amount) FILTER (WHERE credit_account = 'client_committed_security'),0) -COALESCE(SUM(amount) FILTER (WHERE debit_account = 'client_committed_security'),0) AS committed,
         COALESCE(SUM(amount) FILTER (WHERE credit_account = 'client_funded_security'),0) -COALESCE(SUM(amount) FILTER (WHERE debit_account = 'client_funded_security'),0) AS funded
  FROM
    retail.accounting_entries
  GROUP BY account_id,entered_at
)
SELECT
  cd.account_ps_id      ,
  cd.user_name          ,
  cd.ira_account_number ,
  abp.statement_begin_date,
  sum(abp.cash + abp.committed + abp.funded) as Begin_Balance,
  abc.statement_end_date,
  sum(abc.cash + abc.committed + abc.funded) as End_Balance
FROM customer_details cd
  JOIN account_balances_current abc ON cd.account_id = abc.account_id
  JOIN account_balances_previous abp ON cd.account_id = abp.account_id
GROUP BY
  cd.account_ps_id,
  cd.user_name,
  cd.ira_account_number,
  abp.statement_begin_date,
  abc.statement_end_date

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

试试这个

CREATE TABLE Statement
  ( Account_ID VARCHAR(100),
    User_Name VARCHAR(100),
    IRA VARCHAR(100),
    Statement_Date VARCHAR(100),
    Starting_Balance VARCHAR(100)
  );


INSERT INTO Statement VALUES(123456789,'John Smith',123,'11/30/2016','$249,800.00');
INSERT INTO Statement VALUES(123456789,'John Smith',123,'12/31/2016','$250,617.31');
INSERT INTO Statement VALUES(123456789,'John Smith',123,'1/31/2017','$253,016.75');
INSERT INTO Statement VALUES(789123456,'Cate Jones',789,'4/30/2017','$15,000.00');
INSERT INTO Statement VALUES(789123456,'Cate Jones',789,'5/31/2017','$15,045.23');
INSERT INTO Statement VALUES(789123456,'Cate Jones',789,'6/30/2017','$15,144.66');

SELECT *
  FROM (SELECT S.*,
               LEAD(Starting_Balance) OVER 
                 ( PARTITION BY user_name
                       ORDER BY CAST(Statement_Date AS DATE)
                 ) AS ending_balance,
               LEAD(CAST(Statement_Date AS DATE)) OVER 
                 ( PARTITION BY user_name
                       ORDER BY CAST(Statement_Date AS DATE)
                 ) AS end_date         
          FROM Statement AS S
       ) AS TMP
 WHERE TMP.ending_balance IS NOT NULL;