Tôi nghĩ bạn có thể thay thế hầu hết mã của mình bằng truy vấn sau. Bạn có thể cần phải điều chỉnh điều khoản IN, đây là một điều khó khăn nếu bạn đang thay đổi danh sách khách hàng nhiều. Nhưng điều này lặp lại kết quả của bạn:
SELECT *
FROM (SELECT DECODE(ppc.customer_class_code, 'E', c.description, ppc.customer_class_code) AS IDENTIFIER, tpp.item_code, tpp.price AS ITEM_PRICE, ppc.price
FROM table_price_list tpl
INNER JOIN table_price_product tpp ON tpp.list_header_id = tpl.list_header_id AND tpp.request_id = tpl.request_id
INNER JOIN prices_per_client ppc ON tpp.item_code = ppc.item_code
LEFT JOIN clients c ON ppc.customer_number = c.account_number
WHERE SYSDATE BETWEEN NVL(tpp.start_date_active, SYSDATE) AND NVL(tpp.end_date_active, SYSDATE+1))
PIVOT (AVG(PRICE) FOR IDENTIFIER IN ('A' AS CLASS_A , 'B' AS CLASS_B, 'SUPERMARKET' AS SUPERMARKET, 'WALMART' AS WALMART));
Đây là bản cập nhật fiddle .
Đối với đầu ra JSON, sẽ dễ dàng hơn nhiều nếu bạn sử dụng phiên bản mới hơn vì nó hiện là một phần của chức năng cốt lõi.
CHỈNH SỬA:Thêm Chức năng XML cho mỗi Nhận xét
Bạn có thể xem truy vấn này:
SELECT XMLSERIALIZE(CONTENT
XMLELEMENT("Item",
XMLATTRIBUTES(sub.item_code AS "SKU", sub.item_price AS "Price"),
XMLELEMENT("PRICES_FOR_CLIENTS",
XMLAGG(XMLELEMENT("CLIENT_PRICE",
XMLFOREST(sub.identifier AS "Client", sub.price AS "Price"))))) AS CLOB INDENT)
FROM (SELECT DECODE(ppc.customer_class_code, 'E', c.description, ppc.customer_class_code) AS IDENTIFIER, tpp.item_code, tpp.price AS ITEM_PRICE, avg(ppc.price) AS PRICE
FROM table_price_list tpl
INNER JOIN table_price_product tpp ON tpp.list_header_id = tpl.list_header_id AND tpp.request_id = tpl.request_id
INNER JOIN prices_per_client ppc ON tpp.item_code = ppc.item_code
LEFT JOIN clients c ON ppc.customer_number = c.account_number
WHERE SYSDATE BETWEEN NVL(tpp.start_date_active, SYSDATE) AND NVL(tpp.end_date_active, SYSDATE+1)
GROUP BY DECODE(ppc.customer_class_code, 'E', c.description, ppc.customer_class_code), tpp.item_code, tpp.price) sub
WHERE sub.identifier IS NOT NULL
GROUP BY sub.item_code, sub.item_price;
Đây là một câu đố cập nhật với truy vấn đó ( Liên kết ).
Cái nào tạo ra kết quả sau:
<Item SKU="99342435" Price="9999">
<PRICES_FOR_CLIENTS>
<CLIENT_PRICE>
<Client>WALMART</Client>
<Price>40340</Price>
</CLIENT_PRICE>
<CLIENT_PRICE>
<Client>SUPERMARKET</Client>
<Price>48343</Price>
</CLIENT_PRICE>
<CLIENT_PRICE>
<Client>B</Client>
<Price>33223</Price>
</CLIENT_PRICE>
<CLIENT_PRICE>
<Client>A</Client>
<Price>29223</Price>
</CLIENT_PRICE>
</PRICES_FOR_CLIENTS>
</Item>
Chỉnh sửa 2:Thêm JSON qua Kết nối chuỗi
Phần sau sẽ xuất ra JSON thông qua kết nối chuỗi trực tiếp:
SELECT '{"sku":"'||sub.item_code||'","PRICE":"'||sub.item_price||'",PRICES_FOR_CLIENTS:['||listagg('{"group":"'||sub.identifier||'","PRICE":"'||sub.price||'"}',',') WITHIN GROUP (ORDER BY sub.identifier)||']};' AS JSON
FROM (SELECT DECODE(ppc.customer_class_code, 'E', c.description, ppc.customer_class_code) AS IDENTIFIER, tpp.item_code, replace(tpp.price, ',', '.') AS ITEM_PRICE, REPLACE(avg(ppc.price), ',', '.') AS PRICE,
tpl.request_id, max(tpl.request_id) over (partition by tpp.item_code) as max_request
FROM table_price_list tpl
INNER JOIN table_price_product tpp ON tpp.list_header_id = tpl.list_header_id AND tpp.request_id = tpl.request_id
INNER JOIN prices_per_client ppc ON tpp.item_code = ppc.item_code
LEFT JOIN clients c ON ppc.customer_number = c.account_number
WHERE SYSDATE BETWEEN NVL(tpp.start_date_active, SYSDATE) AND NVL(tpp.end_date_active, SYSDATE+1)
GROUP BY DECODE(ppc.customer_class_code, 'E', c.description, ppc.customer_class_code), tpp.item_code, tpp.price, tpl.request_id) sub
WHERE sub.identifier IS NOT NULL
and sub.request_id = sub.max_request
GROUP BY sub.item_code, sub.item_price;
Và một thủ thuật cập nhật với truy vấn này ( Liên kết )
Chỉnh sửa 3:Đã thêm thay thế ** Chỉnh sửa 4:Đã thêm chức năng phân tích **