postgresql 如果列中有逗号分隔的值,为了在where条件下使用它,我使用了split_part,但是在pgAdmin 4中花费了更多的时间

oo7oh9g9  于 2023-02-04  发布在  PostgreSQL
关注(0)|答案(2)|浏览(148)

在PostgreSQL中,我有一个receipt_id列,其中包含逗号分隔的值或单个值。

我需要将第三列中的值与另一个名为Voucher的表一起使用。
我使用了split_part。

select  ap.document_no AS invoice_number,
    ap.curr_date AS invoice_date,ap.receipt_id,split_part(ap.receipt_id::text, ','::text, 1),
    split_part(ap.receipt_id::text, ','::text, 2)
    from ap_invoice_creation ap , voucher v 
    where  (v.voucher_id::text IN      
           ( SELECT split_part(ap_invoice_creation.receipt_id::text, ','::text, 1) AS parts
           FROM ap_invoice_creation
          WHERE ap_invoice_creation.receipt_id::text = ap.receipt_id::text
        UNION
         SELECT split_part(ap_invoice_creation.receipt_id::text, ','::text, 2) AS parts
           FROM ap_invoice_creation
          WHERE ap_invoice_creation.receipt_id::text = ap.receipt_id::text
        UNION
         SELECT split_part(ap_invoice_creation.receipt_id::text, ','::text, 3) AS parts
           FROM ap_invoice_creation
          WHERE ap_invoice_creation.receipt_id::text = ap.receipt_id::text)) AND ap.status::text = 'Posted'::text

但是这是查询的一部分,它需要更多的时间。因为整个查询需要更多的时间。
有没有其他办法来处理这件事?

nuypyhwy

nuypyhwy1#

理想情况下,你甚至不应该这样存储CSV。也就是说,这里不需要SPLIT_PART()和大而丑陋的联合。考虑一下这个版本:

SELECT
    ap.document_no AS invoice_number,
    ap.curr_date AS invoice_date,
    ap.receipt_id,
    SPLIT_PART(ap.receipt_id::text, ',', 1),
    SPLIT_PART(ap.receipt_id::text, ',', 2)
FROM ap_invoice_creation ap
INNER JOIN voucher v 
    ON ',' || ap.receipt_id || ',' LIKE '%,' || v.voucher_id::text || ',%';
sqserrrh

sqserrrh2#

提高性能的一种方法是去除可怕的CSV值,并以适当的一对多关系存储数据。
如果无法做到这一点,可以使用EXISTS条件,而不是使用IN条件的交叉联接,后者使用三个查询:

select ap.document_no AS invoice_number,
       ap.curr_date AS invoice_date,
       ap.receipt_id,
       split_part(ap.receipt_id, ',', 1),
       split_part(ap.receipt_id, ',', 2)
from ap_invoice_creation ap 
WHERE EXISTS (select *
              from voucher v
              where v.voucher_id = any (string_to_array(ap.receipt_id, ',')))
WHERE ap.status = 'Posted'

相关问题