Создание JSON и редактирование сложного запроса (oracle 11g) - PullRequest
4 голосов
/ 31 марта 2020

У меня есть 4 разных таблицы:

table_price_product (содержит информацию о продуктах и ​​их цене)

table_price_list (содержит информацию, связанную с прайс-листом)

Prices_per_client (содержит информацию, относящуюся к ценам для разных клиентов с указанным c продуктом)

клиентов (содержит информацию, относящуюся к клиентам)

This моя SQL FIDDLE: LINK

Я получил это:

CUSTOMER_NUMBER  |  CUSTOMER_CLASS_CODE|    PRICE
(null)           |           A         |    29223
(null)           |           B         |    33223
112121           |           E         |    40340
119435           |           E         |    40340

Теперь я хочу получить в одном запросе все данные, связанные с продуктами и клиенты, замените A, B, C et c на CLASS A, CLASS B, CLASS C соответственно , но , если customer_class_code = = 'E', из которого я хочу получить имя таблица клиенты И, наконец, конвертируйте все и получите JSON для каждого продукта. Взгляните на это, каким-то образом мне нужно добавить столбцы «PRICES_FOR_CLIENTS» и «группы», потому что мне нужны эти столбцы для генерации JSON.

SKU     |PRICE|PRICES_FOR_CLIENTS|groups|CLASS A|CLASS B|WALMART|SUPERMARKET
99342435|9999 |                  |      |29223  |33223  |40340  |40340

image

Я хотел бы сгенерировать JSON с этой информацией:

{"sku": "99342435", "PRICE": "9999", PRICES_FOR_CLIENTS: [{"" group ":" CLASS A "," PRICE ":" 29223 "}, {" group ":" CLASS B "," PRICE ":" 33223 "}, {" group ":" WALMART "," PRICE ":" 40340 "}, {" group ":" SUPERMARKET "," PRICE ":" 40340 "}]};

Вы можете мне помочь?

EDIT:

<Item SKU="99342435" Price="9999">
    <PRICES_FOR_CLIENTS>
        <CLIENT_PRICE>
            <Client>WALMART</Client>
            <Price>40340</Price>
            <Site>USSITE</Site>
        </CLIENT_PRICE>
        <CLIENT_PRICE>
            <Client>SUPERMARKET</Client>
            <Price>48343</Price>
            <Site>USSITE</Site>
        </CLIENT_PRICE>
        <CLIENT_PRICE>
            <Client>B</Client>
            <Price>33223</Price>
            <Site>USSITE</Site>
        </CLIENT_PRICE>
        <CLIENT_PRICE>
            <Client>A</Client>
            <Price>29223</Price>
            <Site>USSITE</Site>
        </CLIENT_PRICE>
    </PRICES_FOR_CLIENTS>
</Item>

1 Ответ

4 голосов
/ 31 марта 2020

Я думаю, вы можете заменить большую часть кода следующим запросом. Возможно, вам придется изменить предложение IN, что является проблемой, если вы сильно меняете список клиентов. Но это повторяет ваши результаты:

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));

Вот обновление fiddle .

Что касается вывода JSON, было бы намного проще, если бы вы были на более поздняя версия, поскольку она теперь является частью основных функций.

РЕДАКТИРОВАТЬ: Добавление XML Функциональность в комментарии

Вы можете проверить этот запрос:

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;

Вот обновленная скрипта с этим запросом ( Ссылка ).

, которая выдает следующий вывод:

<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>

Редактировать 2 : Добавление JSON через конкатенацию строк

В результате прямого конкатенации строк будет выведено JSON:

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;

И обновленная скрипка с этим запросом ( Ссылка )

Редактировать 3: добавлена ​​замена ** Редактировать 4: добавлена ​​аналитическая функция **

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...