闲游四疯 2017-10-11 03:36 采纳率: 0%
浏览 325

T-SQL 排序的算法怎么实现不会遇到越界的问题

create table #Instrument(InstrumentCode varchar(20),Orderln int)
insert into #Instrument(InstrumentCode,Orderln)
select '03',1
union all
select '0301',1
union all
select '0302',3
union all
select '0303',4
union all
select '030102',1
union all
select '030101',2
union all
select '030202',1
union all
select '030201',2
union all
select '030203',3
union all
select '030301',1
union all
select '030302',2
union all
select '03010102',1
union all
select '03010101',2
union all
select '03010103',3
union all
select '03010104',4
union all
select '03010201',1
union all
select '03010202',2
union all
select '03010203',3
union all
select '03020101',1
union all
select '03020102',2
union all
select '03020202',1
union all
select '03020201',2
union all
select '03020301',1
union all
select '03020302',2
union all
select '03020303',3

create table #temp(InstrumentCode varchar(20),OrderId bigint)

;with w as
(select a.InstrumentCode,Parent=a1.InstrumentCode
,leve=1,ParentOrder=a1.Orderln
from #Instrument as a
inner join #Instrument as a1
on left(a.InstrumentCode,len(a.InstrumentCode)-2)=a1.InstrumentCode
union all
select w.InstrumentCode,b.InstrumentCode,leve=w.leve+1
,b.Orderln
from w
inner join #Instrument as b
on left(w.InstrumentCode,len(w.InstrumentCode)-(w.leve+1)*2)=b.InstrumentCode
where len(w.InstrumentCode)>((w.leve+1)*2)
)
insert into #temp(InstrumentCode,OrderId)
select w1.InstrumentCode,ww.ParentOrder+w1.Orderln
from #Instrument as w1
join Instrument ins on w1.InstrumentCode=ins.InstrumentCode
outer apply(select w.InstrumentCode
,sum(POWER(100,w.leve)*w.ParentOrder) as ParentOrder
from w
where w1.InstrumentCode=w.InstrumentCode
group by w.InstrumentCode
) as ww
option(MAXRECURSION 0)

select *
from #temp

drop table #Instrument
drop table #temp


每两位code表示一个层,OrderLn 是单个分支里面的同一个层的排序顺序。
sum(POWER(100,w.leve)*w.ParentOrder)
如果层次太多的话产生越界
有什么好的算法可以既避免越界,又可以实现同一层次的全部进行排序

  • 写回答

1条回答

  • lshen01 2023-03-16 10:19
    关注

    参考GPT和自己的思路:

    针对这个问题,可以使用字符串拆分和排序的方式进行排序。首先,将 InstrumentCode 按照每两个字符拆分成一个小分支,并存储每个小分支的信息,然后在每个小分支内部按照 OrderLn 进行排序。接下来,构建一个以每个小分支为节点的树状结构,每个节点的权值为其所有父节点的权值与 OrderLn 的乘积和。最后,对这个树状结构进行深度优先遍历,按照节点的权值进行排序输出即可。这种算法可以避免越界,同时也考虑到了同一层次的排序问题。具体的实现可以参考下面的示例代码:

    
    -- 构建按照每两个字符拆分成的小分支  
    ;WITH cte AS  
    (  
        SELECT  
            InstrumentCode = LEFT(InstrumentCode,LEN(InstrumentCode) - 2),  
            Sub = RIGHT(InstrumentCode,2),  
            OrderLn  
        FROM  
            #Instrument  
    )  
    -- 对每个小分支进行排序  
    , cteSorted AS  
    (  
        SELECT  
            InstrumentCode,  
            Sub,  
            OrderLn,  
            ROW_NUMBER() OVER(PARTITION BY InstrumentCode ORDER BY OrderLn) AS RowNum  
        FROM  
            cte  
    )  
    -- 构建树状结构  
    , cteTree AS  
    (  
        SELECT  
            InstrumentCode,  
            Sub,  
            [Level] = ROW_NUMBER() OVER (ORDER BY InstrumentCode ASC),  
            OrderLn,  
            ParentCode = NULL  
        FROM  
            cteSorted  
        WHERE  
            RowNum = 1  
        UNION ALL  
        SELECT  
            cteSorted.InstrumentCode,  
            cteSorted.Sub,  
            [Level] = cteTree.[Level] + 1,  
            cteSorted.OrderLn,  
            ParentCode = cteTree.Sub + '.' + cteTree.ParentCode  
        FROM  
            cteSorted  
            INNER JOIN cteTree ON cteTree.InstrumentCode = cteSorted.InstrumentCode  
        WHERE  
            cteSorted.RowNum = 1 OR cteTree.[Level] = cteSorted.RowNum - 1  
    )  
    -- 计算节点权值  
    , cteWeight AS  
    (  
        SELECT  
            InstrumentCode,  
            Sub,  
            [Level],  
            Weight = SUM(OrderLn * POWER(100,[Level]))  
        FROM  
            cteTree  
        GROUP BY  
            InstrumentCode,  
            Sub,  
            [Level]  
    )  
    -- 深度优先遍历并排序输出  
    SELECT  
        t.InstrumentCode,  
        t.Sub  
    FROM  
        cteTree AS t  
        INNER JOIN cteWeight AS w ON t.InstrumentCode = w.InstrumentCode AND t.Sub = w.Sub  
    ORDER BY  
        w.Weight  
    

    总体的思路就是将 InstrumentCode 按照每两个字符进行拆分并排序,在构建树结构并计算节点权值后进行深度优先遍历。在这个过程中,只需要维护每个节点的 InstrumentCode 和 Sub 信息即可,无需考虑越界的问题。

    评论

报告相同问题?

悬赏问题

  • ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能