表结构:
|--------------------------------|-------------|
|branchid |branchcode |parentid|branchtypeid |
|-----------------------|--------|-------------|
|438 |UKHQR |438 | 2 |
|-----------|-----------|--------|-------------|
|539 |UKBRS |438 | 1 |
|-----------|-----------|--------|-------------|
|3683 |UKSNL |438 | 2 |
|-----------|-----------|--------|-------------|
|3110 |UKNNX |3683 | 1 |
|-----------|-----------|--------|-------------|
|987 |FNOLR |987 | 2 |
|-----------|-----------|--------|-------------|
|1014 |FNHLK |987 | 1 |
|-----------|-----------|--------|-------------|
|3371 |FNHPO |987 | 2 |
|-----------|-----------|--------|-------------|
|990 |FNAAA |3371 | 1 |
|--------------------------------|-------------|
branchcode
和branchid
相同且parentid
为2的branchtypeid
是第一个父分支。一个branchcode
和branchid
不相同但parentid
为2的branchtypeid
是第二个父分支,否则这是一个子分支。
子分支应该按照其父分支的排序方式进行排序。
|--------------------------------|-------------|
|branchid |branchcode |parentid|branchtypeid |
|-----------------------|--------|-------------|
|438 |UKHQR |438 | 2 |
|-----------|-----------|--------|-------------|
|987 |FNOLR |987 | 2 |
|-----------|-----------|--------|-------------|
|3683 |UKSNL |438 | 2 |
|-----------|-----------|--------|-------------|
|3371 |FNHPO |987 | 2 |
|-----------|-----------|--------|-------------|
|539 |UKBRS |438 | 1 |
|-----------|-----------|--------|-------------|
|3110 |UKNNX |3683 | 1 |
|-----------|-----------|--------|-------------|
|1014 |FNHLK |987 | 1 |
|-----------|-----------|--------|-------------|
|990 |FNAAA |3371 | 1 |
|--------------------------------|-------------|
我已经完成的事情:
SELECT branchcode,branchid,parentid
FROM branches
START WITH parentid IN ( SELECT parentid FROM branches where parentid = branchid)
CONNECT BY NOCYCLE PRIOR parentid = branchid
ORDER SIBLINGS BY parentid;
答案 0 :(得分:0)
您的代码的主要问题-假设您希望返回所有级别的数据-您只获得具有顶级父级的行(即级别1和2)。这是因为您的start with
子句是寻找任何父母ID;然后您的connect by
搜索错误的方式。这样您的查询就会得到六行:
BRANCHCODE BRANCHID PARENTID
---------- ---------- ----------
UKHQR 438 438
UKBRS 539 438
UKSNL 3683 438
FNOLR 987 987
FNHLK 1014 987
FNHPO 3371 987
..全部具有两个原始顶级ID 438或987之一。
如果要解决这些问题,首先要获取两个真正的顶级父级(而不是使用子查询),然后反转连接方式:
SELECT branchcode, branchid, parentid
FROM branches
START WITH parentid = branchid
CONNECT BY NOCYCLE parentid = PRIOR branchid
ORDER SIBLINGS BY parentid;
BRANCHCODE BRANCHID PARENTID
---------- ---------- ----------
UKHQR 438 438
UKBRS 539 438
UKSNL 3683 438
UKNNX 3110 3683
FNOLR 987 987
FNHLK 1014 987
FNHPO 3371 987
FNAAA 990 3371
...您将以更正常的顺序获得全部8行。顺便说一下,nocycle
仅由于定义顶层的方式而需要;以我的经验,根元素的父ID为null更常见。无论如何,避免该循环的另一种方法是:
CONNECT BY parentid = PRIOR branchid AND branchid != PRIOR parentid
但是我离题了。您可以添加更多信息,包括层次结构的缩进视图:
SELECT branchcode, branchid, parentid,
lpad(' ', level - 1, ' ') || branchcode as nestedbranch
FROM branches
START WITH parentid = branchid
CONNECT BY NOCYCLE parentid = PRIOR branchid
ORDER SIBLINGS BY parentid;
BRANCHCODE BRANCHID PARENTID NESTEDBRANCH
---------- ---------- ---------- ---------------
UKHQR 438 438 UKHQR
UKBRS 539 438 UKBRS
UKSNL 3683 438 UKSNL
UKNNX 3110 3683 UKNNX
FNOLR 987 987 FNOLR
FNHLK 1014 987 FNHLK
FNHPO 3371 987 FNHPO
FNAAA 990 3371 FNAAA
但是您说过,您希望所有的父母都在顶部,这有点奇怪,并且使既是父母又是孩子的行处于不确定状态。您可以通过在顺序中使用case表达式来实现此目的,可能包括上下文的根元素(以及有用的级别),例如:
SELECT branchcode, branchid, parentid,
CONNECT_BY_ROOT(branchcode) AS rootbranch,
lpad(' ', level - 1, ' ') || branchcode as nestedbranch
FROM branches
START WITH parentid = branchid
CONNECT BY NOCYCLE parentid = PRIOR branchid
ORDER BY CASE WHEN branchid = parentid THEN 1 ELSE 2 END, -- puts all parents first
CONNECT_BY_ROOT(branchid), level, branchcode;
BRANCHCODE BRANCHID PARENTID ROOTBRANCH NESTEDBRANCH
---------- ---------- ---------- ---------- ---------------
UKHQR 438 438 UKHQR UKHQR
FNOLR 987 987 FNOLR FNOLR
UKBRS 539 438 UKHQR UKBRS
UKSNL 3683 438 UKHQR UKSNL
UKNNX 3110 3683 UKHQR UKNNX
FNHLK 1014 987 FNOLR FNHLK
FNHPO 3371 987 FNOLR FNHPO
FNAAA 990 3371 FNOLR FNAAA
但是那似乎仍然没有什么用处...所以也许您真的想让每个父母都在其子女之前,而早先的查询确实如此。