gpt4 book ai didi

sql - 根据两列的范围重复行

转载 作者:行者123 更新时间:2023-12-04 10:19:31 26 4
gpt4 key购买 nike

我创建了一个 fiddle here 对于以下数据和我尝试过的查询。

我有如下表。

enter image description here

我的预期输出如下

enter image description here

逻辑:

我必须创建如上所示的报告。逻辑是从起始编号到结束 Material 编号重复相同的行。找出差异,如果有差异,则重复每个 Material 编号的行。所有其他列值保持不变。

数据格式。

  • MaterialNo 将只有一个连字符。(varchar 类型)
  • 连字符前后的字符数可能会有所不同。
  • 差异可能高达 150。

  • 所以我试过的
    WITH cte
    AS (
    SELECT Materialno_start,Materialno_end,name,mtype,noofstock
    ,starts.st AS ns,ends.ed AS nd,diff.s AS d,i = 1
    ,n = convert(VARCHAR(30), starts.st)
    ,n.base AS bs
    FROM data
    CROSS APPLY (VALUES (len(Materialno_start))) leng(mn)
    CROSS APPLY (VALUES (charindex('-', Materialno_start)) ) s(hyp)
    CROSS APPLY (VALUES (substring(Materialno_start, s.hyp - leng.mn + 1, leng.mn))) n(base)
    CROSS APPLY (VALUES (substring(Materialno_start, s.hyp + 1, leng.mn)) ) starts(st)
    CROSS APPLY (VALUES (substring(coalesce(Materialno_end, Materialno_start), s.hyp + 1, leng.mn)) ) ends(ed)
    CROSS APPLY (VALUES (convert(INT, ends.ed) - convert(INT, starts.st))) diff(s)

    UNION ALL

    SELECT Materialno_start,Materialno_end,name,mtype,noofstock ,ns,nd,d,i = i + 1
    ,n = convert(VARCHAR(30), n + 1)
    ,bs
    FROM cte
    WHERE i <= d
    )
    SELECT Materialno_start
    ,Materialno_end
    ,bs + n AS MaterialNo
    ,Name
    ,mtype
    ,noofstock
    FROM cte
    ORDER BY 1

    它给了我所需的输出。但我不确定它是否有效,因为有这么多 CROSS APPLY我的生产数据可能有大约 70k 行,拆分后可能会达到 120k 行。我想知道是否可以通过任何其他方式更有效地完成此操作,或者我可以在此查询中改进哪些方面。我无权访问生产数据或 QA。所以我无法在真实数据中进行测试。我得到了 100 行的样本数据,我使用这个查询来实现我的输出。

    最佳答案

    简单来说,一个 Tally 看起来像这样:

    WITH N AS(
    SELECT N
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
    Tally AS(
    SELECT TOP (200)
    ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
    FROM N N1, N N2, N N3)
    SELECT *
    FROM Tally;

    然后我怀疑你想要做什么,替换 rCTe(和一些十字架适用),将是这样的:
    WITH N AS
    (SELECT N
    FROM (VALUES (NULL),
    (NULL),
    (NULL),
    (NULL),
    (NULL),
    (NULL),
    (NULL),
    (NULL),
    (NULL),
    (NULL)) N (N) ),
    Tally AS
    (SELECT TOP (200)
    ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS I
    FROM N N1,
    N N2,
    N N3),
    cte AS
    (SELECT D.Materialno_start,
    D.Materialno_end,
    D.Name,
    D.MType,
    D.Noofstock,
    CONCAT(LEFT(D.Materialno_start,CHARINDEX('-',D.Materialno_start)),V.NoStart + ISNULL(T.I,0)) AS NewID
    FROM dbo.[data] D
    CROSS APPLY (VALUES(TRY_CONVERT(int,STUFF(D.Materialno_start,1,CHARINDEX('-',D.Materialno_start),'')),TRY_CONVERT(int,STUFF(D.Materialno_end,1,CHARINDEX('-',D.Materialno_end),'')))) V(NoStart,NoEnd)
    LEFT JOIN Tally T ON T.I <= V.NoEnd - V.NoStart)
    SELECT Materialno_start,
    Materialno_end,
    Materialno_start AS MaterialNo,
    Name,
    mtype,
    noofstock,
    NewID
    FROM cte
    ORDER BY cte.Materialno_start;

    关于sql - 根据两列的范围重复行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60926986/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com