ฉันจะจัดกลุ่มข้อมูลตามวันที่ผ่านไปและจำนวนใน PostgreSQL ได้อย่างไร (‹30, 31-60, 61-90, 91+)

ฉันยังใหม่กับ PostgreSQL และกำลังเขียนคำสั่ง SQL โดยทั่วไป ดังนั้นฉันจึงต้องการความช่วยเหลือเล็กน้อย

ข้อมูลทั้งหมดของฉันอยู่ในตารางเดียว (บัญชี) และฉันต้องดึงค่าเงินดอลลาร์ (จำนวนการกู้คืน) สองวันที่ (appeal_date และ recovery_date) และสุดท้ายจัดกลุ่มข้อมูลตามผลต่างของ appeal_date และ recovery_date เพื่อดู การกู้คืนทั้งหมด_จำนวนเมื่อครบกำหนด

เช่น (recovery_date -อุทธรณ์_date) ในหน่วยวัน = recovery_amount ทั้งหมด ใน ‹30 วัน, recovery_amount ทั้งหมด ใน 31-60 วัน, recovery_amount ทั้งหมด ใน 61-90 วัน และ recovery_amount ทั้งหมดในช่วง 90 วัน

ฉันกำลังลองใช้ข้อความเช่น:

SELECT recovery_amount AS "Total"
CASE
  when (appeal_date - payment_date) >= 90 then 90
  when (appeal_date - payment_date) >= 60 then 60
  when (appeal_date - payment_date) >= 30 then 30
  else 0
END GROUP
FROM accounts
GROUP BY "Total"

เป้าหมายสุดท้ายคือการใช้ข้อมูลนี้บนกราฟแท่ง (หากช่วยให้คุณเห็นภาพเหตุผลได้)

เห็นได้ชัดว่านี่เป็นวิธีปิด เนื่องจากฉันได้ลองใช้รูปแบบต่างๆ มากมายแต่ก็ไม่เกิดประโยชน์ใดๆ

ความช่วยเหลือใด ๆ ที่พวกคุณสามารถให้ได้นั้นได้รับการชื่นชมอย่างมาก! ขอบคุณล่วงหน้า!


person jmoneygram    schedule 07.10.2016    source แหล่งที่มา


คำตอบ (4)


ไม่ไกล...

SELECT  
sum(recoveryTotal) as TotalAmount, --if you want the overall total
sum (case when (appeal_date - payment_date) >= 90 then recoveryTotal else 0 end) as total90,
sum (case when (appeal_date - payment_date) >= 60 then recoveryTotal else 0 end)as total60,
sum (case when (appeal_date - payment_date) >= 30 then recoveryTotyl else 0 end) as total30
FROM accounts
person Raphaël Althaus    schedule 07.10.2016

หากคุณต้องการเก็บข้อมูลเป็น 3 คอลัมน์

SELECT count(*) NoOfAccts, sum(recovery_amount) AS "GroupTotal"
CASE
  when (appeal_date - payment_date) >= 90 then 90
  when (appeal_date - payment_date) >= 60 then 60
  when (appeal_date - payment_date) >= 30 then 30
  else 0
END GROUP
FROM accounts
GROUP BY CASE
  when (appeal_date - payment_date) >= 90 then 90
  when (appeal_date - payment_date) >= 60 then 60
  when (appeal_date - payment_date) >= 30 then 30
  else 0
END 

ก็จะส่งผลอะไรประมาณนั้น

NoOfAccts   GroupTotal    Group
22          3754.48       90
96          24834.83      60
123         38348.48      30
9999        1824389.83    0
person xQbert    schedule 07.10.2016
comment
ขอบคุณที่ช่วยเหลือฉัน! - person jmoneygram; 07.10.2016

วิธีแก้ไขประการหนึ่งคือการรวมแบบมีเงื่อนไข (ดูคำตอบของRaphaël)

หากคุณไม่ต้องการให้เป็นคอลัมน์แยกกันจริงๆ คุณสามารถทำให้คอลัมน์นี้มีความไดนามิกมากขึ้น (=ง่ายต่อการรักษา) หากคุณใช้รายการช่วง เนื่องจากคุณกำลังวางแผนที่จะใช้สิ่งนั้นสำหรับรายงาน นั่นก็ควรจะไม่เป็นไร

with limits (range) as (
  values 
    (int4range(0,30,'[)')),
    (int4range(30,60,'[)')),
    (int4range(60,90,'[)')),
    (int4range(90,null,'[)'))
)
select l.range as day_range,
       sum(coalesce(recovery_amount,0)) as total
from limits l
  left join accounts ac
    on (ac.appeal_date - ac.payment_date) <@ l.range
group by range
order by range;

ตัวอย่าง: http://rextester.com/UYDOV15732

ตอนนี้ถ้าคุณต้องการช่วงใหม่ คุณเพียงเพิ่มช่วงนั้นลงในรายการช่วงโดยไม่ต้องเปลี่ยนแบบสอบถามจริง คุณสามารถสร้างช่วงที่มีขนาดเท่ากันโดยอัตโนมัติจากข้อมูลที่ปรับตามข้อมูลในตารางโดยอัตโนมัติ

person a_horse_with_no_name    schedule 07.10.2016

ควรสามารถใช้ DATE_PART เพื่อค้นหาความแตกต่างเป็นวันได้ http://www.sqlines.com/postgresql/how-to/datediff.

ดังนั้น หากฉันเข้าใจถูกต้องว่าคุณกำลังพยายามจัดกลุ่มจำนวนเงินที่กู้คืนทั้งหมดตามส่วนต่างของวันที่ อย่างเช่น:

    SELECT CASE DATE_PART('day', appeal_date - payment_date)
            WHEN <= 30 THEN '<=30'
            WHEN BETWEEN 31 and 60 THEN '31-60'
            WHEN BETWEEN 61 and 90 THEN '61-90'
            WHEN > 90 THEN '>90'
            ELSE 0
        END as 'DateRange',
        SUM(recovery_amount) AS "Total"
    FROM accounts
    GROUP BY CASE DATE_PART('day', appeal_date - payment_date)
            WHEN <= 30 THEN '<=30'
            WHEN BETWEEN 31 and 60 THEN '31-60'
            WHEN BETWEEN 61 and 90 THEN '61-90'
            WHEN > 90 THEN '>90'
            ELSE 0
        END
person William    schedule 07.10.2016
comment
ฉันค้นคว้าลิงก์นั้นแล้ว... ขอบคุณสำหรับความช่วยเหลือ! - person jmoneygram; 07.10.2016