我如何在Oracle SQL中获得字符串拆分结果的Carbohydrate产品,数组中的所有条目都是JSON对象中的键?

uajslkp6  于 2023-10-16  发布在  Oracle
关注(0)|答案(1)|浏览(67)

我怎样才能得到一个字符串分割结果的卡巴拉乘积,数组中的所有条目都是JSON对象中的键?这是我最接近答案的一次

SELECT REGEXP_SUBSTR(scp, '[^ ]+', 1, level), aud
  FROM (SELECT scp, aud
           FROM JSON_TABLE('{
                              "s": "s1 s2 s3",
                              "a": [
                                "a1",
                                "a2",
                                "a3"
                              ]
                            }' FORMAT JSON,
            '$[*]' COLUMNS(
                            scp VARCHAR2 PATH '$.s',
                            NESTED PATH '$.a[*]'
                            COLUMNS(
                                     aud VARCHAR2 PATH '$[*]'
                                   )
                            )
                            )
        )
CONNECT BY REGEXP_SUBSTR(scp, '[^ ]+', 1, level) IS NOT NULL

但它只对a1分解每个s。我希望得到9个条目,Map每个s到每个a。如何通过一个JSON_TABLE查询实现这一点?

xienkqul

xienkqul1#

不能使用JSON函数拆分字符串。
您可以使用简单的字符串函数(比正则表达式快得多)和递归子查询分解子句拆分字符串:

WITH rsqfc (scp, aud, spos, epos) AS (
  SELECT scp,
         aud,
         1,
         INSTR(scp, ' ', 1)
  FROM   JSON_TABLE(
           '{"s": "s1 s2 s3","a": ["a1","a2","a3"]}' FORMAT JSON,
           '$[*]'
           COLUMNS(
             scp VARCHAR2 PATH '$.s',
             NESTED PATH '$.a[*]' COLUMNS(
               aud VARCHAR2 PATH '$[*]'
             )
           )
         )
UNION ALL
  SELECT scp,
         aud,
         epos + 1,
         INSTR(scp, ' ', epos + 1)
  FROM   rsqfc
  WHERE  epos > 0
)
SELECT CASE epos
       WHEN 0
       THEN SUBSTR(scp, spos)
       ELSE SUBSTR(scp, spos, epos - spos)
       END AS scp,
       aud
FROM   rsqfc;

在Oracle 12中,您还可以使用CROSS APPLY

SELECT REGEXP_SUBSTR(scp, '[^ ]+', 1, lvl) AS scp,
       aud
FROM   JSON_TABLE(
         '{"s": "s1 s2 s3","a": ["a1","a2","a3"]}' FORMAT JSON,
         '$[*]'
         COLUMNS(
           scp VARCHAR2 PATH '$.s',
           NESTED PATH '$.a[*]' COLUMNS(
             aud VARCHAR2 PATH '$[*]'
           )
         )
       )
       CROSS APPLY (
         SELECT LEVEL AS lvl
         FROM   DUAL
         CONNECT BY LEVEL <= REGEXP_COUNT(scp, '[^ ]+')
       );

两者输出:
| SCP| AUD|
| --|--|
| S1| A1|
| S1| A2|
| S1| A3|
| S2| A1|
| S2| A2|
| S2| A3|
| S3| A1|
| S3| A2|
| S3| A3|
fiddle

相关问题