我需要帮助构建查询,因为下面的structured.i尝试使用for循环,但它只是打印为1 2 3 4 5 6 7 8 9
例如,如果N值为9则表示输出应该是这样的。
示例输出:
0
0 1
0 1 2
0 1 2 3
0 1 2 3 4
0 1 2 3 4 5
0 1 2 3 4 5 6
0 1 2 3 4 5 6 7
0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 6 7
0 1 2 3 4 5 6
0 1 2 3 4 5
0 1 2 3 4
0 1 2 3
0 1 2
0 1
0
答案 0 :(得分:2)
要在SQL中执行此操作 - 如果您希望能够指定n
,则需要使用绑定变量 - 您需要将start与connect by
组合并从那里构建。这是一种方式,但我非常确定可以在没有union
的情况下完成:
with t as (
select level as rn, level - 1 as val
from dual
connect by level <= :n + 1
)
select t1.rn as rn,
listagg(t2.val, ' ') within group (order by t2.val) as answer
from t t1
join t t2 on t2.val <= t1.val
group by t1.rn, t1.val
union all
select (2 * (:n + 1)) - t1.rn,
listagg(t2.val, ' ') within group (order by t2.val) as answer
from t t1
join t t2 on t2.val <= t1.val
where t1.rn <= :n
group by t1.rn, t1.val
order by rn;
CTE生成数字0到n。联合的两半创造了输出的镜像半部;第二个有rn <= :n
过滤器,以防止“中间”过滤线被重复。
使用:
var n number;
exec :n := 9;
这给出了:
RN ANSWER
------ ----------------------------------------
1 0
2 0 1
3 0 1 2
4 0 1 2 3
5 0 1 2 3 4
6 0 1 2 3 4 5
7 0 1 2 3 4 5 6
8 0 1 2 3 4 5 6 7
9 0 1 2 3 4 5 6 7 8
10 0 1 2 3 4 5 6 7 8 9
11 0 1 2 3 4 5 6 7 8
12 0 1 2 3 4 5 6 7
13 0 1 2 3 4 5 6
14 0 1 2 3 4 5
15 0 1 2 3 4
16 0 1 2 3
17 0 1 2
18 0 1
19 0
或6:
exec:n:= 6;
RN ANSWER
------ ----------------------------------------
1 0
2 0 1
3 0 1 2
4 0 1 2 3
5 0 1 2 3 4
6 0 1 2 3 4 5
7 0 1 2 3 4 5 6
8 0 1 2 3 4 5
9 0 1 2 3 4
10 0 1 2 3
11 0 1 2
12 0 1
13 0
你真的不想看到rn
,但你可以通过将它放在子查询中来删除它。
答案 1 :(得分:1)
使用while循环:
DECLARE
my_limit SIMPLE_INTEGER := 9;
my_step SIMPLE_INTEGER := +1;
i SIMPLE_INTEGER := 0;
s VARCHAR2(32000);
BEGIN
WHILE (i > -1) LOOP
s := '';
FOR j IN 0 .. i LOOP
IF j>0 THEN s := s || ' '; END IF;
s := s || to_char(j);
END LOOP;
dbms_output.put_line(s);
IF (i >= my_limit) THEN my_step := -1; END IF;
i := i + my_step;
END LOOP;
END;
/
答案 2 :(得分:1)
我认为, sys_connect_by_path 正是您所寻找的。 p>
SYS_CONNECT_BY_PATH仅在分层查询中有效。它返回从根到节点的列值的路径,对于CONNECT BY条件返回的每一行,列值由char分隔。
with desired_number as (select 5 as nm from dual)
,tree
as ( select level - 1 as a, sys_connect_by_path(level - 1, ' ') as b, nm
from dual, desired_number
connect by level <= nm + 1)
select *
from (select a, b from tree
union all
select 2 * nm - a, b
from tree
where a != nm)
order by a
不过,你怎么像sql那样格式化它?
答案 3 :(得分:1)
此选择查询可提供准确的结果:
WITH CTE1 AS
(SELECT 9 AS COL FROM DUAL)
,CTE2
AS (
SELECT LEVEL - 1 AS A,
SYS_CONNECT_BY_PATH(LEVEL - 1, ' ') AS B,
COL
FROM DUAL, CTE1
CONNECT BY LEVEL <= COL + 1)
SELECT B
FROM (SELECT A, B FROM CTE2
UNION ALL
SELECT 2 * COL - A, B
FROM CTE2
WHERE A != COL)
ORDER BY A;
<强>输出:强>
0
0 1
0 1 2
0 1 2 3
0 1 2 3 4
0 1 2 3 4 5
0 1 2 3 4 5 6
0 1 2 3 4 5 6 7
0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 6 7
0 1 2 3 4 5 6
0 1 2 3 4 5
0 1 2 3 4
0 1 2 3
0 1 2
0 1
0
答案 4 :(得分:0)
您可能会发现通过建立连接,以便找到答案。
select level n
from dual
connect by level <= 10
答案 5 :(得分:0)
使用三个嵌套for循环:
DECLARE
my_limit SIMPLE_INTEGER := 9;
PROCEDURE one_line(n simple_integer) IS
s VARCHAR2(4000);
BEGIN
FOR j IN 0 .. n LOOP
IF j>0 THEN s := s || ' '; END IF;
s := s || to_char(j);
END LOOP;
dbms_output.put_line(s);
END one_line;
BEGIN
FOR i IN 0 .. my_limit LOOP
one_line(i);
END LOOP;
FOR i IN REVERSE 0 .. my_limit-1 LOOP
one_line(i);
END LOOP;
END;
/
答案 6 :(得分:0)
终于明白了:
WITH CTE AS
(
SELECT LEVEL-1 COL
FROM DUAL
CONNECT BY LEVEL <= 10
)
SELECT SYS_CONNECT_BY_PATH(COL, ' ') COL
FROM ( SELECT COL,
ROW_NUMBER() OVER (ORDER BY COL) RN
FROM CTE)
START WITH RN = 1
CONNECT BY PRIOR RN = RN - 1
UNION ALL
SELECT COL FROM(
SELECT RPAD(SYS_CONNECT_BY_PATH(COL, ' ') , '20' )COL
FROM ( SELECT COL,
ROW_NUMBER() OVER (ORDER BY COL) RN
FROM CTE)
START WITH RN = 1
CONNECT BY PRIOR RN = (RN - 1 )
ORDER BY COL DESC
);
生成此输出:
0
0 1
0 1 2
0 1 2 3
0 1 2 3 4
0 1 2 3 4 5
0 1 2 3 4 5 6
0 1 2 3 4 5 6 7
0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 6 7
0 1 2 3 4 5 6
0 1 2 3 4 5
0 1 2 3 4
0 1 2 3
0 1 2
0 1
0