一、最原始的表说明


Sql代码  

 
   
 
1. CREATE TABLE
2. (  
3. NOT NULL,  
4. NAME
5.   VALUE        VARCHAR2(100 BYTE),  
6.   PARENTID     NUMBER,  
7. SEQUENCE
8.   DESCRIPTION  VARCHAR2(1000 BYTE)  
9. )

 

 datadic 是一张树状的数据字典表,dataId:主键  value:对应的值  parentId:父节点的主键

 使用select * from datadic 查询完数据对应的值如下:


 约定:根的id为0,可以看到根下面有两条记录,分别行业数据,政务数据。

版次及其他版本形式下面有九个子节点,也就是九条根据,分别为3版、1 版、2版……增订本、2版(修订本)

要实现的最终效果是:

   parentID(父节点id)     parentValue(父节点值)    childvalue(子节点值)

        0                                    根                         行业数据*政务数据

      ……                                 ……                        ……

        140                             版次及其他版本形式    3版*1 版*2版……增订本*2版(修订本)

二、取按照parentid分组,组内部按照dataid排序后的行号


Sql代码  

sql server 2022 多行转多列 sql多行变一行_伪列

 
  
 
 
1. select
2.                 t.value,   
3.                 t.dataid,  
4.                 (row_number()  /* 按照parentid分组,组内部按照dataid排序后的行号*/  
5. by parentid order by
6.                 ) numid   
7. from

查询后的记录集如下:


这个记录表示,parentId为0的记录有6条,numid就是按照parentId分组后按照dataid排序后的rownum.

 

row_number()   over(partition by 分组列 order by 排序列)

还有相关的函数:

      rank() over(partition by 分组列 order by 排序列)   :和名次一样,并列2个之后是第三名

      densrank() over(partition by 分组列 order by 排序列)   :连续顺序,有2个第二名,仍然跟前第三名。

三、按照上面的行号进行轮循,进行组内每行字符串的连接。


Sql代码   
   

 
   
 
1. select
2. '*'), '*') valuues   
3. from (select
4.                    t.value,   
5.        t.dataid,  
6. as
7.                    (row_number()  /* 按照parentid分组,组内部按照dataid排序后的行号*/  
8. by t.parentid order by
9.                     ) numid   
10. from
11. where
12.    )   
13. WHERE
14. with
15. connect by numid - 1 = prior numid    and parentid = prior


 查询结果如下,可以看到显示父节点id、父节点值、父节点下所有子节点的值。


sys_connect_by_path(value, '*')
     value表示要连接的字段,‘*’表示连接符。
    使用这个方法之前必须在where条件中构建树
    where start with 条件1  connect by prior 条件2
   条件1 :表示起始条件,例如,起始条件为组内排序后的rownum为1。
valuues  对应的值是:“出版行业*版权行业”。那么“版权行业”与“出版行业”之间的关系是:相同的parentId中的numid+1,所以其条件为:
        start with numid = 1 
        connect by numid - 1 = prior numid    and parentid = prior parentid;其中,prior.列名:代表上一行的列。
  
 SYS_CONNECT_BY_PATH :实现将从父节点到当前行内容以“path”或者层次元素列表的形式显示出来
  
 CONNECT_BY_ROOT: 它用在列名之前用于返回当前层的根节点
  
 connect_by_isleaf:来判断当前行是不是叶子。如 果是叶子就会在伪列中显示“1”,如果不是叶子而是一个分支(例如当前内容是其他行的父亲)就显示“0”。
  
 CONNECT_BY_ISCYCLE:Oracle 10g 之前的版本中,如果在你的树中出现了环状循环(如一个孩子节点引用一个父亲节点),Oracle 就会报出一个错误提示:“ ORA-01436: CONNECT BY loop in user data”。如果不删掉对父亲的引用就无法执行查询操作。而在 Oracle 10g 中,只要指定“NOCYCLE”就可以进行任意的查询操作。与这个关键字相关的还有一个伪列——CONNECT_BY_ISCYCLE, 如果在当前行中引用了某个父亲节点的内容并在树中出现了循环,那么该行的伪列中就会显示“1”,否则就显示“0”。
  
  
 

    Sql代码   
   

 
   
 
1. select temp.CASE_ID,ltrim(max(sys_connect_by_path(temp.name,'//')),'//')  
2. from
3. (   select asso.CASE_ID as
4. NAME as name,  
5. by asso.CASE_ID order by
6. from
7. where
8. )temp
9. start with temp.numid=1  
10. connect by temp.CASE_ID=prior temp.CASE_ID  
11. and temp.numid-1=prior temp.numid  
12. group by temp.CASE_ID