使用SQL中的拆分记录

发布于 2025-02-01 21:06:08 字数 932 浏览 5 评论 0原文

我有一张具有以下记录

前缀以下前缀开始端部div行业
1AB0000199999li 1abri
1AB005270052700528 mhugri

我想将其分配为

前缀ri 1 ab ri ri 1enddiv行业
1AB0000199999lpsdri
1ab00527 0052700528mhugri
1 abri 1 ab ri005271abri

ab 00529999999999999999999999999999999999999999999.如果您看到的是因为我们有一个具有相同前缀的记录,但开始和结束是不同的,我想将第一个记录分为2个记录,一个从00001到00526,再到00529,再到99999

。 SQL查询

I have an table with the below records

PREFIXBEGINENDDIVINDUSTRY
1AB0000199999LPSDRI
1AB0052700528MHUGRI

I want to split it as below

PREFIXBEGINENDDIVINDUSTRY
1AB0000199999LPSDRI
1AB0052700528MHUGRI
1AB0052999999LPSDRI

If you see as because we have a record with the same prefix but begin and end are different, i want to split the first record into 2 records, one from 00001 to 00526 and 00529 to 99999.

Is it possible to perform the same using the SQL query

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

淡墨 2025-02-08 21:06:08

我认为这有效(但是它需要更大的数据集来正确测试):

SELECT prefix,
       "BEGIN",
       "END",
       CASE type
       WHEN 1
       THEN div
       ELSE LAG(CASE type WHEN 1 THEN div END) IGNORE NULLS
              OVER (PARTITION BY prefix, industry, grp ORDER BY "BEGIN")
       END AS div,
       industry
FROM   (
  SELECT prefix,
         div,
         industry,
         value AS "BEGIN",
         type,
         SUM(type) OVER (PARTITION BY prefix, industry ORDER BY value) AS grp,
         LEAD(value) OVER (PARTITION BY prefix, industry ORDER BY value) AS "END"
  FROM   table_name
  UNPIVOT (value FOR type IN ("BEGIN" AS 1, "END" AS -1))
)
WHERE  grp > 0
ORDER BY prefix, industry, "BEGIN";

对于示例数据:

CREATE TABLE table_name (prefix, "BEGIN", "END", div, industry) AS
SELECT '1AB', '00001', '99999', 'LPSD', 'RI' FROM DUAL UNION ALL
SELECT '1AB', '00527', '00528', 'MHUG', 'RI' FROM DUAL;

输出:

前缀beginenddiv行业
1ab0000100527lpsdri
1ab0052700528mhugri
1ab0052899999lpsdri

db<<>> gt; gt; gt; A3F630E04D8DBBB rel =“ nofollow noreferrer”>此处

I think this works (but it would need a bigger data set to test it properly):

SELECT prefix,
       "BEGIN",
       "END",
       CASE type
       WHEN 1
       THEN div
       ELSE LAG(CASE type WHEN 1 THEN div END) IGNORE NULLS
              OVER (PARTITION BY prefix, industry, grp ORDER BY "BEGIN")
       END AS div,
       industry
FROM   (
  SELECT prefix,
         div,
         industry,
         value AS "BEGIN",
         type,
         SUM(type) OVER (PARTITION BY prefix, industry ORDER BY value) AS grp,
         LEAD(value) OVER (PARTITION BY prefix, industry ORDER BY value) AS "END"
  FROM   table_name
  UNPIVOT (value FOR type IN ("BEGIN" AS 1, "END" AS -1))
)
WHERE  grp > 0
ORDER BY prefix, industry, "BEGIN";

Which, for the sample data:

CREATE TABLE table_name (prefix, "BEGIN", "END", div, industry) AS
SELECT '1AB', '00001', '99999', 'LPSD', 'RI' FROM DUAL UNION ALL
SELECT '1AB', '00527', '00528', 'MHUG', 'RI' FROM DUAL;

Outputs:

PREFIXBEGINENDDIVINDUSTRY
1AB0000100527LPSDRI
1AB0052700528MHUGRI
1AB0052899999LPSDRI

db<>fiddle here

一抹淡然 2025-02-08 21:06:08

首先,在保留单词后(例如开始,结束...),命名列并不是一个好习惯。可以使用这样的模型子句来解决这...

    WITH
        tbl AS
            (   Select '1AB' "PRFX", '00001' "BGN", '99999' "ND", 'LPSD' "DV", 'RI' "IND" From Dual UNION ALL
                Select '1AB' "PRFX", '00527' "BGN", '00528' "ND", 'MHUG' "DV", 'RI' "IND" From Dual
            ) 
    SELECT DISTINCT
        m.*,
        t.DV "DV",
        t.IND "IND"
    FROM
        (
    SELECT
        INDX,
        PRFX, BGN, ND
    FROM
        (   SELECT
                PRFX "PRFX",
                LISTAGG(BGN, ',') WITHIN GROUP (ORDER BY PRFX, BGN) "BGN",
                LISTAGG(ND, ',') WITHIN GROUP (ORDER BY PRFX, ND) "ND"
            FROM
                tbl 
            GROUP BY
                PRFX
        )
    MODEL
        DIMENSION BY(0 as INDX)
        MEASURES (PRFX, BGN, ND)
            RULES ITERATE(3) 
                (   PRFX[ITERATION_NUMBER+1] = PRFX[0],
                    BGN[ITERATION_NUMBER+1] = Nvl(SubStr(REPLACE(BGN[0], ',', ''), (ITERATION_NUMBER*5) + 1, 5), LPAD(To_Number(SubStr(REPLACE(ND[0], ',', ''), ((ITERATION_NUMBER-2)*5) + 1, 5)) + 1, 5, '0')),
                    ND[ITERATION_NUMBER+1] = CASE 
                                                WHEN SubStr(REPLACE(BGN[0], ',', ''), ((ITERATION_NUMBER+1)*5) + 1, 5) < SubStr(REPLACE(ND[0], ',', ''), (ITERATION_NUMBER*5) + 1, 5) THEN
                                                    LPAD(To_Number(SubStr(REPLACE(BGN[0], ',', ''), ((ITERATION_NUMBER+1)*5) + 1, 5)) - 1, 5, '0')
                                              ELSE 
                                                  SubStr(REPLACE(ND[0], ',', ''), ((ITERATION_NUMBER-1)*5) + 1, 5) 
                                              END
                )
        ) m
    LEFT JOIN
        (   SELECT 
                PRFX, DV, 
                IND, 
                Max(ND) OVER(PARTITION BY PRFX, DV ORDER BY PRFX, DV) "MAX_ND",
                Min(BGN) OVER(PARTITION BY PRFX, DV ORDER BY PRFX, DV) "MIN_BGN"
            FROM 
                tbl
        )  t ON (t.PRFX = m.PRFX And (t.MAX_ND = m.ND OR t.MIN_BGN = m.BGN)) 
WHERE
    m.INDX > 0 And ND Is Not Null
ORDER BY 
    m.INDX
    --
    -- Result
    -- INDX PRFX BGN    ND      DV      IND
    -- 1    1AB  00001  00526   LPSD    RI
    -- 2    1AB  00527  00528   MHUG    RI
    -- 3    1AB  00529  99999   LPSD    RI

希望它会有所帮助。问候...

First of all it is not a good practice to name columns after reserved words (like Begin, End ...). This could be solved using MODEL clause like this...

    WITH
        tbl AS
            (   Select '1AB' "PRFX", '00001' "BGN", '99999' "ND", 'LPSD' "DV", 'RI' "IND" From Dual UNION ALL
                Select '1AB' "PRFX", '00527' "BGN", '00528' "ND", 'MHUG' "DV", 'RI' "IND" From Dual
            ) 
    SELECT DISTINCT
        m.*,
        t.DV "DV",
        t.IND "IND"
    FROM
        (
    SELECT
        INDX,
        PRFX, BGN, ND
    FROM
        (   SELECT
                PRFX "PRFX",
                LISTAGG(BGN, ',') WITHIN GROUP (ORDER BY PRFX, BGN) "BGN",
                LISTAGG(ND, ',') WITHIN GROUP (ORDER BY PRFX, ND) "ND"
            FROM
                tbl 
            GROUP BY
                PRFX
        )
    MODEL
        DIMENSION BY(0 as INDX)
        MEASURES (PRFX, BGN, ND)
            RULES ITERATE(3) 
                (   PRFX[ITERATION_NUMBER+1] = PRFX[0],
                    BGN[ITERATION_NUMBER+1] = Nvl(SubStr(REPLACE(BGN[0], ',', ''), (ITERATION_NUMBER*5) + 1, 5), LPAD(To_Number(SubStr(REPLACE(ND[0], ',', ''), ((ITERATION_NUMBER-2)*5) + 1, 5)) + 1, 5, '0')),
                    ND[ITERATION_NUMBER+1] = CASE 
                                                WHEN SubStr(REPLACE(BGN[0], ',', ''), ((ITERATION_NUMBER+1)*5) + 1, 5) < SubStr(REPLACE(ND[0], ',', ''), (ITERATION_NUMBER*5) + 1, 5) THEN
                                                    LPAD(To_Number(SubStr(REPLACE(BGN[0], ',', ''), ((ITERATION_NUMBER+1)*5) + 1, 5)) - 1, 5, '0')
                                              ELSE 
                                                  SubStr(REPLACE(ND[0], ',', ''), ((ITERATION_NUMBER-1)*5) + 1, 5) 
                                              END
                )
        ) m
    LEFT JOIN
        (   SELECT 
                PRFX, DV, 
                IND, 
                Max(ND) OVER(PARTITION BY PRFX, DV ORDER BY PRFX, DV) "MAX_ND",
                Min(BGN) OVER(PARTITION BY PRFX, DV ORDER BY PRFX, DV) "MIN_BGN"
            FROM 
                tbl
        )  t ON (t.PRFX = m.PRFX And (t.MAX_ND = m.ND OR t.MIN_BGN = m.BGN)) 
WHERE
    m.INDX > 0 And ND Is Not Null
ORDER BY 
    m.INDX
    --
    -- Result
    -- INDX PRFX BGN    ND      DV      IND
    -- 1    1AB  00001  00526   LPSD    RI
    -- 2    1AB  00527  00528   MHUG    RI
    -- 3    1AB  00529  99999   LPSD    RI

Hopefully it will help. Regards...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文