使用lpad函数格式化分层查询

时间:2014-04-24 13:45:01

标签: sql oracle

SELECT LPAD(last_name, LENGTH(last_name)+(LEVEL*2)-2,'_') 
AS org_chart
FROM employees 
START WITH last_name='King' 
CONNECT BY PRIOR employee_id=manager_id ;

LPAD(char1,n [,char2]) returns char1, left-padded to length n with the sequence 
of characters in char2.

这告诉SQL抓住LAST_NAME并用“_”字符左键填充它直到 结果字符串的长度等于

确定的值
LENGTH(last_name)+(LEVEL*2)-2. 
For  LEVEL = 1. Hence, (2 * 1) - 2 = 2 - 2 = 0. 
For LEVEL = 2. Hence, (2 * 2) - 2 = 4 - 2 = 2 . So its gets padded with 2 '_' 

字符并以缩进方式显示。

以及如何确定要添加级别* 2-2

的长度(ename)的公式

输出为王不会填充' - '

这是正确的输出

ORG_CHART

    KING
    __PAUL
    __JONES
    ____SCOTT
    ______ADAMS
    ____FORD
    ______SMITH
    __BLAKE
    ____ALLEN
    ____WARD
    ____MARTIN
    ____TURNER
    ____JAMES
    __CLARK
    ____MILLER

但是公式lpad(国王,4 +(l * 10)-10,' - ')=> lpad(国王,4,' - ')

这意味着国王应该填充4' - '

1 个答案:

答案 0 :(得分:1)

您需要包含字段的长度,因为您必须允许其中的字符数,加上您想要的缩进量。以第三级格林伯格为例,显示为:

____Greenberg

...有四个下划线。这里的等级是3,所以(level * 2) - 2是4。但如果你只使用了这个价值,你就会得到:

lpad('Greenberg', 4, '_')

并且输出只是:

Gree

您希望最终输出字符串(包括下划线)比其自身的名称​​长四个字符'Greenberg'为9个字符,____Greenberg为13个字符;所以你的填充长度必须是13,这是名称的长度加上你想要出现在前面的下划线的数量。

获得相同效果的另一种方法是:

SELECT LPAD('_', (LEVEL - 1) * 2, '_') || last_name AS org_chart
...

这使下划线填充与名称本身分开 - 它仅基于关卡,名称最后连接在一起。


对于King,级别为1.您说公式为:

lpad(king,4+(l*10)-10,'-')=>lpad(king,4,'-')

哪个是正确的,但是'King'已经有四个字符长,所以将其填充为四个字符无效。你将它填充到4的最终长度。lpad无论如何都不会添加四个下划线;它只会在请求的长度上添加下划线,在这种情况下为4。

我认为你只是误解了这个功能是如何运作的。 As the documentation says(强调补充):

  

LPAD返回expr1左边填充到n个字符   expr2中的字符序列   ...
  参数n 返回值的总长度,因为它显示在终端屏幕上。

所以:

select lpad('King',4,'_') from dual;

LPAD('KING',4,'_')
------------------
King          

如果您要求更长的最终长度,您可以获得将'King'填充到该长度所需的下划线数量:

select lpad('King',5,'_') from dual;

LPAD('KING',5,'_')
------------------
_King              

如果你想要King缩进,也可以用两个下划线缩进;和后续级别缩进以匹配(因此Kochhar获得4而Greenberg获得6)然后从计算中删除-2