有没有一种方法可以将某些列分组为一组列? PostgreSQL

时间:2020-09-28 22:09:36

标签: arrays postgresql

我有一个查询,可在其中查询客户信息,他的贷款以及每笔超过约定金额30%的付款。就像您必须支付20美元并支付30美元一样,它将显示该笔付款。问题是,如果您在同一时期内进行两次或三次付款,则所有客户数据都会重复。我已经进行了查询。但是对于该报告,我想将付款数据分组到一个数组中(我正在使用rails并使用其方法来使其缓慢)以xlsx视图打印。所有渲染部分均已完成。 事情是将查询的输出转换为我期望的输出:

data = pd.DataFrame({'Project':  ['Project 1', 'Project 2', ' Project 3', 'Project 4', 'Project 5', 'Project 6', 'Project 7', 'Project 8', 'Project 9', 'Project 10'],
        'Date': ['10/1/2020', '10/1/2020', '11/1/2020', '12/1/2020', '12/1/2020', '12/1/2020', '2/1/2021', '2/1/2021', '3/1/2021', '4/1/2021'],
       'Team': ['Team 1', 'Team 2', 'Team 3', 'Team 2', 'Team 2', 'Team 2', 'Team 1', 'Team 1', 'Team 1', 'Team 1'],
       'Timely': ['Yes', 'No', 'No', 'Yes', 'Yes', 'No', 'No', 'Yes', 'Yes', 'Yes']})
                                       
df1=data.groupby('Team')['Timely'].apply(lambda x: (x=='Yes').sum()).reset_index(name='Yes Count')       

df1

我想要的输出:

  Columns      |   type     |
-----------------------------
|fullname      |text        |  <--- From this
|id_number     |string      |
|loan          |string      |
|obligation    |numeric     |
|balance       |numeric     |
|loan_start    |date        |  <--- Until here, are the data that will repeat. (client data)
|code          |string      |  <--- from this and below are the columns that change for each
|pmt_date      |date        |       payment. (payment data)
|bill_amt      |numeric     |
|pmt_amt       |numeric     |
|dif           |numeric     |  <--- This is the difference between bill_amount and amount
|note          |text        |
-----------------------------
  Columns      |   type     |
-----------------------------
|fullname      |text        |  <--- From this
|id_number     |string      |
|loan          |string      |
|obligation    |numeric     |
|balance       |numeric     |
|loan_start    |date        |  <--- Until here (client data)
|payments      |array       |  <--- each array will have an array with the payment data or json
|totals        |array       |  <--- This will have the sum of bill_amt, pmt_amt and dif
-----------------------------

谢谢!

1 个答案:

答案 0 :(得分:0)

经过研究,我得到了这个解决方案:

SELECT
  id,
  fullname AS "Nombre del cliente",
  id_number AS "Ruc o Cédula",
  loan AS "N° Préstamo",
  loan_start AS "Fecha",
  obligation AS "M.Obligacióm",
  balance AS "Saldo Prest.",
  json_agg(                             <-- using json_agg to make an array of
    json_build_array(                       payments and json_build_array to make
      code,                                 an array with each payment data
      pmt_date,
      bill_amt,
      pmt_amt,
      dif,
      TRIM(
        regexp_replace(
          note, 
          E'[\\n\\r---]+', 
          ' ', 
          'g' 
        )
      )
    )
  ) AS payments,
  json_build_array(                     <-- make an array for the sum of charge
    sum(charge),
    sum(amount),
    sum(dif)
  )
FROM (
  SELECT
    client.id AS id,
    payment.codigo AS code,
    alertable_type,
    payment.payment_date AS date,
    lm.lm AS bill_amt,
    amount AS pmt_amt,
    amount - lm.lm AS dif,
    ac.comment AS note,
    fn.full_name AS fullname,
    client.id_number AS id_number,
    loan.codigo AS loan,
    loan.total_loan_amt AS obligation,
    ch.sum AS balance,
    loan.loan_start_date AS loan_start
  FROM 
    prestamas.alerts AS alert
  JOIN prestamas.payments AS payment
  ON alert.alertable_id = payment.id
  JOIN prestamas.loans AS loan
  ON payment.loan_id = loan.id
  JOIN (
    SELECT
      CASE 
        WHEN loan_periodicity = 'Quincenal'
          THEN payment_amt * 2
      ELSE payment_amt
      END AS lm,
      id
    FROM prestamas.loans
  ) AS lm
  ON loan.id = lm.id
  JOIN (
    SELECT
      CASE
        WHEN delete_comment IS NOT NULL THEN delete_comment
        WHEN solve_comment IS NOT NULL THEN solve_comment
        WHEN investigate_comment IS NOT NULL THEN investigate_comment
        WHEN read_comment IS NOT NULL THEN read_comment
        ELSE 'No se ha leído la Alerta'
      END AS "comment",
      id
    FROM prestamas.alerts
  ) AS ac
  ON ac.id = alert.id
  JOIN prestamas.clients AS client
  ON client.id = loan.client_id
  JOIN (
    SELECT
      CONCAT(
        TRIM(first_name),
        ' ',
        TRIM(last_name),
        ' ',
        TRIM(apellido_materno)
      ) AS full_name,
      id
    FROM prestamas.clients
  ) AS fn
  ON fn.id = client.id
  JOIN (
    SELECT
      SUM(balance) AS "sum",
      l.id AS "id"
    FROM prestamas.loans AS l
    JOIN prestamas.charges AS ch
    ON ch.loan_id = l.id
    GROUP BY l.id
  ) AS ch
  ON ch.id = loan.id
  WHERE alertable_type = 'Payment'
  AND payment.payment_date >= DATE('2020-09-01') 
  AND payment.payment_date <= DATE('2020-09-29')
) AS raw
GROUP BY 
  id, 
  fullname, 
  id_number, 
  loan,
  loan_start,
  obligation,
  balance
;

获得我想要的输出。


  Columns      |   type     |
-----------------------------
|fullname      |text        |  <--- From this
|id_number     |string      |
|loan          |string      |
|obligation    |numeric     |
|balance       |numeric     |
|loan_start    |date        |  <--- Until here (client data)
|payments      |json        |  <--- each array will have an array with the payment data or json
|totals        |json        |  <--- This will have the sum of bill_amt, pmt_amt and dif
-----------------------------

非常感谢每个尝试或想要帮助的人!