回答

收藏

找到嵌套集的面包屑

技术问答 技术问答 221 人阅读 | 0 人回复 | 2023-09-14

我正在使用嵌套集被称为修改后的预排序树遍历)来存储组列表,我试图找到一种快速的方法来为所有组生成面包屑(作为字符串,而不是表)。我的数据也使用相邻的表模型(一些触发器可以保持两者同步)。, {4 d9 c2 v# `6 o2 O, v8 `
例如:
- ~3 H- L6 w+ }ID   Name    ParentId  Left   Right0    Node A           1      1211                                                                     Node B                 522                                        2                 5222                                                                             Node C            33     4333                                                                 3333                                                                                                                                                                                                33 3 3 3 3 3  3       3        3            3                                       333                                                                                                                                                                 33333333333333333333                              Node D          6       114                                                                                                                                                                                                                                                                       6                                                                                                                                         6                                                                                                                                                                                 Node E   3                8555                                                                                                                                                                                                     Node F 4          9    代表树:! t9 T+ n1 z+ I1 z% k( g
节点A
1 c* q1 j7 X0 @1 F9 F节点B
6 |5 v! v: `: U& h" Y/ [1 @节点C" m* Y* L1 l2 _2 p
节点D   H) C% A( |7 Z. K, a; L$ U
节点E  l: H; ?7 j6 L& J8 }
节点F
我希望有一个用户定义函数返回表:
" O. k2 k" t& }  W" A7 EID  Breadcrumb0   Node A1   Node A > Node B2   Node A > Node B > Node C3   Node A > Node D4   Node A > Node D > Node E5   Node A > Node D > Node F为了需要遵守用户限制,以使其更加复杂(尽管它超出了问题的范围)。因此,例如,如果我只能访问它id = 3.运行查询时应得到:; u' m( w7 E/ k( e9 |: q8 j
ID  Breadcrumb3   Node D4   Node D > Node E5   Node D > Node F我确实有一个用户定义的函数,它将是一个userid作为参数,返回包含所有有效组的表格ID,因此,只要查询中的某个位置& [( q. m% b( {$ T( G+ B
WHERE group.id IN (SELECT id FROM dbo.getUserGroups(@userid))它会工作。4 E6 N, o/ A+ _
我有一个标量函数可以执行这个操作,但它不适用于任何合理数量的组(需要2000个组)>
  _. W& B% H( O2 C9 {! T10秒)。它使用一个groupid和userid作为参数,返回一个nvarchar。它找到给定的组父母(一个查询以获得左/右值,另一个查询以查找父母),并将列表限制为用户有权访问的组(使用与上述相同的组)WHERE因此,使用另一个查询),然后使用游标遍历每组,并将其添加到字符串中,最后返回值。) ~- M+ P3 Y3 w2 v. G* F3 M
我需要一种可以快速运行的方法
: Z4 R- M0 G7 p3 X2 ]: H这是在SQL Server 2005上。
- G0 |2 f4 L/ {' ^0 i                                                               
( h) g4 R, p6 I0 @    解决方案:                                                                $ w2 C" r8 {6 t
                                                                我最后要做的就是建立一个大型的连接,简单地把这个表和它自己联系起来,遍布每个层次。
! r* Q2 w: X* ~; f7 M首先,我只在第一个级别组中填充表@topLevelGroups(如果你只有一,可以跳过这一步)@userGroups填充用户可以看到的组。
9 _  a3 n2 e) W, j; r7 o" wSELECT groupid,  (level      CASE WHEN level2 IS NOT NULL THEN ' > '   level2 ELSE '' END      CASE WHEN level3 IS NOT NULL THEN ' > '   level3 ELSE '' END   )as [breadcrumb]FROM (  SELECT g3.*    ,g1.name as level1    ,g2.name as level2    ,g3.name as level3  FROM @topLevelGroups g1  INNER JOIN @userGroups g2 ON g2.parentid = g1.groupid and g2.groupid  g1.groupid  INNER JOIN @userGroups g3 ON g3.parentid = g2.groupid  UNION  SELECT g2.*    ,g1.name as level1    ,g2.name as level2    ,NULL as level3  FROM @topLevelGroups g1   INNER JOIN @userGroups g2 ON g2.parentid = g1.groupid and g2.groupid  g1.groupid  UNION  SELECT g1.*    ,g1.name as level1    ,NULL as level2    ,NULL as level3   FROM @topLevelGroups g1) aORDER BY [breadcrumb]这是一项相当大的技能,显然仅限于一定数量的水平(对于我的应用程序,我可以选择一个合理的限制)。问题是,支持的水平越多,连接的数量就会翻倍,所以速度要慢得多。
5 F0 D+ C" u, ]4 E6 D( r在代码中执行此操作肯定更容易,但是对我而言,这并非总是一种选择-有时候我需要直接走SQL此功能在查询中获得。) l) Y, Y5 g; ?& J; v
我接受这个作为答案,因为这是我最后要做的,可能对别人有用-但是,如果有人能提出更有效的方法,我就把它改成他们。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则