本文介绍了编辑输出(根据检索的数量和分号设置括号)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每次运行我的代码时,我都会以 JSON 格式获取一行、两行或几行.我使用的是 Oracle 11g.

Every time that I run my code I obtain one, or two or several rows on a JSON format. I am using Oracle 11g.

这是我在 SQL Fiddle 上的代码,你 在那里找到所有数据.

This is my CODE on SQL Fiddle, you will find all the data there.

例如,在这种情况下,我得到了这样的东西:

For example, in this case I obtained something like this:

{"sku":"99342435","PRICE":"9999",PRICES_FOR_CLIENTS:[{"group":"A","PRICE":"29223"},{"group":"B","PRICE":"33223"},{"group":"SUPERMARKET","PRICE":"48343"},{"group":"沃尔玛","PRICE":"40340"}]};

但我可以根据存储在表中的数据获得此输出:

BUT I could get this output depending on the data stored in the tables:

{"sku":"99342435","PRICE":"9999",PRICES_FOR_CLIENTS:[{"group":"A","PRICE":"29223"},{"group":"B","PRICE":"33223"},{"group":"SUPERMARKET","PRICE":"48343"},{"group":"沃尔玛","PRICE":"40340"}]};

{"sku":"95453343","PRICE":"8778",PRICES_FOR_CLIENTS:[{"group":"A","PRICE":"29223"},{"group":"B","PRICE":"33223"},{"group":"SUPERMARKET","PRICE":"48343"},{"group":"沃尔玛","PRICE":"40340"}]};

{"sku":"95453343","PRICE":"8778",PRICES_FOR_CLIENTS:[{"group":"A","PRICE":"29223"},{"group":"B","PRICE":"33223"},{"group":"SUPERMARKET","PRICE":"48343"},{"group":"WALMART","PRICE":"40340"}]};

我想让我的查询能够在第一行中放置一个左括号",检查是否存在其他行,如果没有显示新行,则插入一个关闭括号在末尾和一个分号;像这样:

I want to make my query able to put an "open bracket" in the first row, check if there exist another rows and if no new rows are shown then, insert a close bracket in the end and a semicolon; something like this:

[{"sku":"99342435","PRICE":"9999",PRICES_FOR_CLIENTS:[{"group":"A","PRICE":"29223"},{"group":"B","PRICE":"33223"},{"group":"SUPERMARKET","PRICE":"48343"},{"group":"沃尔玛","PRICE":"40340"}]}];

但另一种情况可能是存在超过 1 行;在这种情况下,我想在第一行放置一个左括号,而不是一个右括号.我只想打开第一行的括号并在最后一行和分号内关闭它.不同的行必须逗号分隔.请遵循以下示例:

BUT another scenario could be when there exist more than 1 row; in that case I would like to put an open bracket in the first row but not a close bracket. I only want to open the bracket in the first row and close it in the last row and within, a semicolon. The different rows MUST BE separated by a comma. Please, follow this example:

[{"sku":"99342435","PRICE":"9999",PRICES_FOR_CLIENTS:[{"group":"A","PRICE":"29223"},{"group":"B","PRICE":"33223"},{"group":"SUPERMARKET","PRICE":"48343"},{"group":"沃尔玛","PRICE":"40340"}]},

{"sku":"95453343","PRICE":"8778",PRICES_FOR_CLIENTS:[{"group":"A","PRICE":"29223"},{"group":"B","PRICE":"33223"},{"group":"SUPERMARKET","PRICE":"48343"},{"group":"WALMART","PRICE":"40340"}]}];

{"sku":"95453343","PRICE":"8778",PRICES_FOR_CLIENTS:[{"group":"A","PRICE":"29223"},{"group":"B","PRICE":"33223"},{"group":"SUPERMARKET","PRICE":"48343"},{"group":"WALMART","PRICE":"40340"}]}];

我尝试了很多次,但我无法做到.

I tried so many times but I was not able to do it.

你能帮我吗?

推荐答案

这开始落入以下领域:仅仅因为您可以使其工作,并不意味着您应该这样做.但是要回答您的问题,请查看此代码:

This is starting to fall into the realm of just because you can make it work, doesn't mean you should. But to answer your question, check this code out:

SELECT CASE WHEN sub2.TOTAL_ROW > 1 AND sub2.this_row = 1 THEN '[' ELSE NULL END||
       sub2.json||
       CASE WHEN sub2.total_row > 1 AND sub2.this_row = sub2.total_row THEN ']' ELSE NULL END AS JSON
FROM (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,
      COUNT(*) OVER () AS TOTAL_ROW,
      ROW_NUMBER() OVER (ORDER BY sub.item_code, sub.item_price) AS THIS_ROW
      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) sub2
ORDER BY sub2.this_row;

我更新了你的 SQLFiddle

这个查询的作用是扩展上一个查询.它使用分析函数 COUNTROW_NUMBER 计算总行数和这一行.我根本没有对它们进行分区,因为我们希望它们考虑所有返回的行.如果总行数 > 1 且这是第一行,则以["开头.在中间附加 JSON.如果这是最后一行(Total > 1 and ROW_NUMBER = COUNT),则将]"附加到末尾.

What this query does is expand on the previous query. It counts the total rows and this row using the analytic functions COUNT and ROW_NUMBER. I didn't partition them at all because we want them to consider all returned rows. If Total Rows > 1 and this is the first row start it with '['. Append the JSON in the middle. And if this is the last row (Total > 1 and ROW_NUMBER = COUNT) then append ']' to the end.

编辑 1:更改为始终有括号

SELECT DECODE(sub2.this_row, 1, '[', NULL)||
       sub2.json||
       DECODE(sub2.this_row, sub2.total_row, ']', NULL) AS JSON
FROM (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,
      COUNT(*) OVER () AS TOTAL_ROW,
      ROW_NUMBER() OVER (ORDER BY sub.item_code, sub.item_price) AS THIS_ROW
      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) sub2
ORDER BY sub2.this_row;

这是更新后的 SQLFiddle(链接).

Here is the updated SQLFiddle (Link).

考虑到更简单的逻辑,我将 CASE 换成了 DECODE.如果该行是第一行,它将获得左括号.如果是最后一行,则获取右括号.如果两者兼而有之,则两者兼而有之.

Given the simpler logic, I switched out the CASE for DECODE. IF the row is the first row it gets the opening bracket. If it is the last row, it gets the closing bracket. If it is both, it gets both.

这篇关于编辑输出(根据检索的数量和分号设置括号)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 13:53