问题
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.
This tells SQL to take the LAST_NAME and left-pad it with the '_' character till the length of the resultant string is equal to the value determined by
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 '_'
characters and is displayed indented.
and also how to determine the formula that length(ename) to be added with level*2-2
the output is king doesn't get padded with '-'
This is the correct output
ORG_CHART
KING
__PAUL
__JONES
____SCOTT
______ADAMS
____FORD
______SMITH
__BLAKE
____ALLEN
____WARD
____MARTIN
____TURNER
____JAMES
__CLARK
____MILLER
but formula lpad(king,4+(l*10)-10,'-')=>lpad(king,4,'-')
which means king should be padded with 4'-'
回答1:
You need to include the length of the field because you have to allow for the number of characters in that, plus the amount of indentation you want. Taking the third-level Greenberg for example, that is displayed as:
____Greenberg
... with four underscores. Level is 3 here, so (level * 2) - 2
is four. But if you only used that value you'd get:
lpad('Greenberg', 4, '_')
and the output of that is just:
Gree
You want the final output string, including the underscores, to be four characters longer than the name on its own. 'Greenberg'
is 9 characters, and ____Greenberg
is 13; so your padding length has to be 13, which is the length of the name plus the number of underscores you want to appear in front.
Another way to get the same effect is with:
SELECT LPAD('_', (LEVEL - 1) * 2, '_') || last_name AS org_chart
...
That makes the underscore padding separate from the name itself - it's based just on the level, and the name is just concatenated on the end.
For King
, the level is 1. You said the formula is:
lpad(king,4+(l*10)-10,'-')=>lpad(king,4,'-')
Which is right, but 'King'
is already four characters long, so padding it out to four characters has no effect. Your are padding it out to the final length of 4. lpad
doesn't add four underscores regardless; it only adds underscores up to the requested length, which is 4 in this case.
I think you're just misinterpreting how the function workd. As the documentation says (emphasis added):
LPAD
returnsexpr1
, left-padded to lengthn
characters with the sequence of characters inexpr2
.
...
The argumentn
is the total length of the return value as it is displayed on your terminal screen.
So:
select lpad('King',4,'_') from dual;
LPAD('KING',4,'_')
------------------
King
If you asked for a longer final length you'd get the number of underscores needed to pad 'King'
out to that length:
select lpad('King',5,'_') from dual;
LPAD('KING',5,'_')
------------------
_King
If you want King
to be indented as well, by two underscores; and subsequent levels to be indented more to match (so Kochhar
gets 4 and Greenberg
gets 6) then remove the -2
from the calculation.
来源:https://stackoverflow.com/questions/23270781/formatting-hierachical-queries-with-lpad-function