编辑输出(根据检索到的数量和分号设置括号)
Editing the output (set brackets depending on the quantity retrieved and the semicolon)
每次我 运行 我的代码都会以 JSON 格式获得一行、两行或几行。我正在使用 Oracle 11g.
这是我在 SQL Fiddle 上的 CODE,您 将 在那里找到所有数据。
例如,在这种情况下,我得到了这样的东西:
{"sku":"99342435","PRICE":"9999",PRICES_FOR_CLIENTS:[{"group":"A","PRICE":"29223"},{"group":"B","PRICE":"33223"},{"group":"SUPERMARKET","PRICE":"48343"},{"group":"WALMART","PRICE":"40340"}]};
但我可以根据存储在表中的数据获得此输出:
{"sku":"99342435","PRICE":"9999",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"}]};
我想让我的查询能够在 第一行 中放置一个 "open bracket",检查是否存在其他行,如果没有显示新行,在末尾插入一个 右方括号 和一个分号;像这样:
[{"sku":"99342435","PRICE":"9999",PRICES_FOR_CLIENTS:[{"group":"A","PRICE":"29223"},{"group":"B","PRICE":"33223"},{"group":"SUPERMARKET","PRICE":"48343"},{"group":"WALMART","PRICE":"40340"}]}];
但另一种情况可能是存在 多于 1 行;在那种情况下,我想在第一行放置一个 左括号 而不是右括号。我只想打开第一行的括号并在最后一行和分号内关闭它。不同的行 必须 由 逗号 分隔。请按照这个例子:
[{"sku":"99342435","PRICE":"9999",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"}]}];
试了很多次都做不到
你能帮帮我吗?
这开始属于仅仅因为您可以使它起作用的领域,并不意味着您应该这样做。但要回答您的问题,请查看此代码:
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
这个查询所做的是在前一个查询的基础上进行扩展。它使用分析函数 COUNT
和 ROW_NUMBER
计算总行数和这一行数。我根本没有对它们进行分区,因为我们希望它们考虑所有返回的行。如果总行数 > 1 并且这是第一行,则以“[”开头。在中间附加 JSON。如果这是最后一行(总计 > 1 且 ROW_NUMBER
= COUNT
),则将“]”附加到末尾。
编辑 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 (Link)。
鉴于更简单的逻辑,我将 CASE
换成了 DECODE
。如果该行是第一行,它会得到左括号。如果它是最后一行,它会得到右括号。如果两者都是,则两者都得到。
处理此问题的最简单方法是对现有查询的结果执行另一个 LISTAGG
,并将其包含在 [
和 ]
:
中
SELECT '[' || LISTAGG(JSON, ',') WITHIN GROUP(ORDER BY 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
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
) j
注意需要用双引号将PRICES_FOR_CLIENTS
括起来,否则查询的输出是无效的JSON。您还需要从原始查询输出的字符串末尾删除 ;
。
每次我 运行 我的代码都会以 JSON 格式获得一行、两行或几行。我正在使用 Oracle 11g.
这是我在 SQL Fiddle 上的 CODE,您 将 在那里找到所有数据。
例如,在这种情况下,我得到了这样的东西:
{"sku":"99342435","PRICE":"9999",PRICES_FOR_CLIENTS:[{"group":"A","PRICE":"29223"},{"group":"B","PRICE":"33223"},{"group":"SUPERMARKET","PRICE":"48343"},{"group":"WALMART","PRICE":"40340"}]};
但我可以根据存储在表中的数据获得此输出:
{"sku":"99342435","PRICE":"9999",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"}]};
我想让我的查询能够在 第一行 中放置一个 "open bracket",检查是否存在其他行,如果没有显示新行,在末尾插入一个 右方括号 和一个分号;像这样:
[{"sku":"99342435","PRICE":"9999",PRICES_FOR_CLIENTS:[{"group":"A","PRICE":"29223"},{"group":"B","PRICE":"33223"},{"group":"SUPERMARKET","PRICE":"48343"},{"group":"WALMART","PRICE":"40340"}]}];
但另一种情况可能是存在 多于 1 行;在那种情况下,我想在第一行放置一个 左括号 而不是右括号。我只想打开第一行的括号并在最后一行和分号内关闭它。不同的行 必须 由 逗号 分隔。请按照这个例子:
[{"sku":"99342435","PRICE":"9999",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"}]}];
试了很多次都做不到
你能帮帮我吗?
这开始属于仅仅因为您可以使它起作用的领域,并不意味着您应该这样做。但要回答您的问题,请查看此代码:
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
这个查询所做的是在前一个查询的基础上进行扩展。它使用分析函数 COUNT
和 ROW_NUMBER
计算总行数和这一行数。我根本没有对它们进行分区,因为我们希望它们考虑所有返回的行。如果总行数 > 1 并且这是第一行,则以“[”开头。在中间附加 JSON。如果这是最后一行(总计 > 1 且 ROW_NUMBER
= COUNT
),则将“]”附加到末尾。
编辑 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 (Link)。
鉴于更简单的逻辑,我将 CASE
换成了 DECODE
。如果该行是第一行,它会得到左括号。如果它是最后一行,它会得到右括号。如果两者都是,则两者都得到。
处理此问题的最简单方法是对现有查询的结果执行另一个 LISTAGG
,并将其包含在 [
和 ]
:
SELECT '[' || LISTAGG(JSON, ',') WITHIN GROUP(ORDER BY 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
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
) j
注意需要用双引号将PRICES_FOR_CLIENTS
括起来,否则查询的输出是无效的JSON。您还需要从原始查询输出的字符串末尾删除 ;
。