如果oracle的库表的某一字段在的存储形式为10155,10166这种形式,当前台需要通过left join 查出10155和10166对应的名字时,则需要用到先把'10155,10166',这个字段的值先转换为一列,转换成列之后要结合数据进行构造树,然后此问题则变为oracle中的树形查询。
简要解释如下:
oracle中的树查询
regexp_substr+regexp_count
CONNECT BY 子句说明每行数据将是按层次顺序检索,并规定将表中的数据连入
树型结构的关系中。 PRIORY 运算符必须放置在连接关系的两列中某一个的前面。对于节点间的父子关系, PRIOR 运算符在一侧表示父节点,在另一侧表示子节点,从而确定查找树结构是的顺序是自顶向下还是自底向上。在连接关系中,
除了可以使用列名外,还允许使用列表达 式。 START WITH 子句为可选项,用来标识哪个节点作为查找树型结构的根节点。若该子句被省略,则表示所有满足查询条件的行作为根节点
prior关键字意思是,放在=左侧表示,检索顺序从根节点到叶子节点,即由父节点向子节点方向进行检索,自顶向下方式,并且prior要指定父节点;prior放在=右侧,则相反;当sjflid = PRIOR ID时,数据库会根据当前的ID迭代出sjflid与该ID相同的记录,所以查询的结果是迭代出了所有的子类记录;而PRIOR ID = sjflid时,数据库会跟据当前的sjflid来迭代出与当前的sjflid相同的id的记录,所以查询出来的结果就是所有的父类结果,注意:当写法是prior始终在=号左边时以此为依据--当前迭代出来的具体内容是等号右边的内容,不太容易区分prior运算符在一侧表示父节点,在另一侧表示子节点,这一块容易懵逼,注意!
补充:
我们可能会用到PRIOR DBMS_RANDOM.VALUE IS NOT NULL。用来欺骗下oracle。每次循环是不一样的。不然会报ORA-01436: CONNECT BY loop in user data。
附上一段示例代码:
SELECT X3.PK_COST_STANDARD,
X3.ORGID,
X3.ID,
X3.NAME,
X3.CONTROLLEDRANGE,
X3.CREATETIME,
X3.MODIFIER,
X3.MODIFIEDTIME,
WY_CONCAT(X3.STANDARDTYPE_NAME) AS STANDARDTYPE_NAME,
X3.FILE_ID AS STANDARDTYPE,
X3.REMIND,
X3.SUBSIDYTYPE,
X3.STANDARDFILE,
X3.DR,
X3.TS,
X3.CREATER,
X3.LEGALCODE,
A.ORGNAME AS ORGNAME,
P.ORGNAME AS CONTROLLEDRANGE_NAME,
M.STANDARDLIMIT AS STANDARDLIMIT,
M.STANDARDEXPLAIN AS STANARDEXPLAIN,
W.NAME AS REMIND_NAME,
C.EMPNAME AS CREATER_NAME,
D.EMPNAME AS MODIFIER_NAME
FROM (SELECT X.PK_COST_STANDARD,
X.ORGID,
X.ID,
X.NAME,
X.CONTROLLEDRANGE,
X.CREATETIME,
X.MODIFIER,
X.MODIFIEDTIME,
X2.COL_NAME AS STANDARDTYPE_NAME,
X.FILE_ID,
X.STANDARDTYPE,
X.REMIND,
X.SUBSIDYTYPE,
X.STANDARDFILE,
X.DR,
X.TS,
X.CREATER,
X.LEGALCODE
FROM (SELECT PK_COST_STANDARD,
ORGID,
ID,
NAME,
CONTROLLEDRANGE,
CREATETIME,
MODIFIER,
MODIFIEDTIME,
STANDARDTYPE AS FILE_ID,
REGEXP_SUBSTR(STANDARDTYPE, '[^,]+', 1, LEVEL) AS STANDARDTYPE,
REMIND,
SUBSIDYTYPE,
STANDARDFILE,
DR,
TS,
CREATER,
LEGALCODE
FROM (SELECT T.PK_COST_STANDARD,
T.ORGID,
T.ID,
T.NAME,
T.CONTROLLEDRANGE,
T.CREATETIME,
T.MODIFIER,
T.MODIFIEDTIME,
T.STANDARDTYPE,
T.REMIND,
T.SUBSIDYTYPE,
T.STANDARDFILE,
T.DR,
T.TS,
T.CREATER,
T.LEGALCODE
FROM RP_COST_STANDARD T)
CONNECT BY NOCYCLE
LEVEL <= REGEXP_COUNT(STANDARDTYPE, ',')+1
AND PK_COST_STANDARD = PRIOR PK_COST_STANDARD
AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL) X
LEFT JOIN PUB_COL_TABLE_RELATION X2
ON X2.ROWCODE IN X.STANDARDTYPE) X3
LEFT JOIN ORG_ORGANIZATION A
ON A.ORGID = X3.ORGID
LEFT JOIN ORG_EMPLOYEE C
ON C.EMPID = X3.CREATER
LEFT JOIN ORG_EMPLOYEE D
ON D.EMPID = X3.MODIFIER
LEFT JOIN RP_COST_STANDARD_CHILD M
ON M.PK_COST_STANDARD = X3.PK_COST_STANDARD
LEFT JOIN ORG_ORGANIZATION P
ON P.ORGID = X3.ORGID
LEFT JOIN PUB_DATA_DICTIONARY W
ON W.CODE = X3.REMIND
AND W.P_ID = '10146'
WHERE X3.DR = 0
AND M.DR = 0
AND X3.LEGALCODE = '000'
AND X3.ORGID IN (484)
GROUP BY X3.PK_COST_STANDARD,
X3.ORGID,
X3.ID,
X3.NAME,
X3.CONTROLLEDRANGE,
X3.CREATETIME,
X3.MODIFIER,
X3.MODIFIEDTIME,
A.ORGNAME,
P.ORGNAME,
X3.CONTROLLEDRANGE,
M.STANDARDLIMIT,
X3.SUBSIDYTYPE,
X3.STANDARDFILE,
M.STANDARDEXPLAIN,
W.NAME,
X3.REMIND,
C.EMPNAME,
D.EMPNAME,
X3.DR,
X3.TS,
X3.CREATER,
X3.LEGALCODE,
X3.FILE_ID
ORDER BY X3.CREATETIME DESC