[原]SQL解决“俯瞰金字塔”矩阵

俯瞰金字塔
本文通过SQL实现了一个类似金字塔形状的数字阵列,该阵列中间高四周低,形似金字塔。文章提供了Oracle和SQL Server两种环境下生成该阵列的具体SQL代码。

原题是邀月的大作《一个类似于杨辉三角的数组算法思路》,我觉得原文中所谓的“类似于杨辉三角”这个算法比较模糊,所以改成“俯瞰金字塔”,这样显得更形象一点。

 1 1 1 1 1 1 1 1 1 1 1
 1 2 2 2 2 2 2 2 2 2 1
 1 2 3 3 3 3 3 3 3 2 1
 1 2 3 4 4 4 4 4 3 2 1
 1 2 3 4 5 5 5 4 3 2 1
 1 2 3 4 5 6 5 4 3 2 1
 1 2 3 4 5 5 5 4 3 2 1
 1 2 3 4 4 4 4 4 3 2 1
 1 2 3 3 3 3 3 3 3 2 1
 1 2 2 2 2 2 2 2 2 2 1
 1 1 1 1 1 1 1 1 1 1 1

如果将数字看成是高度的话,中间高,四周低是一个很形象的金字塔哈。

废话少说,上SQL:

 

Oracle,SQL Plus中执行:

var v_level number;
exec :v_level := 10;  /* <- n在这里修改 */
with seq as (
  select level v from  dual connect  by level<= :v_level+1
),
matrix as (
  select r.v r,c.v c from seq r,seq c 
),
m01 as (
select 
  r,c,
  least(abs(case when r<=ceil(:v_level/2) then r else :v_level+1+1-r end),
        abs(case when c<=ceil(:v_level/2) then c else :v_level+1+1-c end)) v
from matrix order by r,c
)
select SYS_CONNECT_BY_PATH( v, ' ') matrix
from m01
where level=:v_level+1
start with c=1
connect by prior r=r 
       and prior c=c-1
order by r ;
MATRIX
-------------------------
 1 1 1 1 1 1 1 1 1 1 1
 1 2 2 2 2 2 2 2 2 2 1
 1 2 3 3 3 3 3 3 3 2 1
 1 2 3 4 4 4 4 4 3 2 1
 1 2 3 4 5 5 5 4 3 2 1
 1 2 3 4 5 6 5 4 3 2 1
 1 2 3 4 5 5 5 4 3 2 1
 1 2 3 4 4 4 4 4 3 2 1
 1 2 3 3 3 3 3 3 3 2 1
 1 2 2 2 2 2 2 2 2 2 1
 1 1 1 1 1 1 1 1 1 1 1

解析一下,其实思路很简单,很暴力,设定 n=10 吧,

select level v from dual connect by level<= 10+1

产生一个 1~11的序列;

select r.v r,c.v c from seq r,seq c

全连接,产生一个 11*11的矩阵(r,c),r和c的取值范围在 1~11 之间

select
  r,c,
  least(abs(case when r<=ceil(10/2) then r else 10+1+1-r end),
        abs(case when c<=ceil(10/2) then c else 10+1+1-c end)) v
from matrix order by r,c

有点算法的味道吧,对于某一点(r,c)的数值 v 有以下等式:

v = least(abs(case when r<=ceil(10/2) then r else 10+1+1-r end),
          abs(case when c<=ceil(10/2) then c else 10+1+1-c end))

least 是求最小值的函数。

 

SQL Server(需要SQL Server 2005或以上):

declare @level int;
set @level=10;  -- n在这里修改
with seq as (
  select v from ( 
	  select
		row_number() over (order by object_id) v
	  from sys.objects
  )a
  where v<=@level+1
),
matrix as (
select 
  r.v r,c.v c, ( select MIN(v) from 
         ( select case when r.v<=ceiling(@level/2) then r.v else @level+1+1-r.v end as v 
           union all 
           select case when c.v<=ceiling(@level/2) then c.v else @level+1+1-c.v end as v 
          )a
        ) as v
from seq r,seq c
),
cte as (
  select 0 as lvl,r,c,cast(v as varchar(100)) as line 
    from matrix where c=1
  union all 
  select lvl+1,m.r ,m.c , cast(c.line+' '+cast(m.v as varchar) as varchar(100)) as line 
    from cte c,matrix m 
    where c.r=m.r and m.c=c.c+1
)
select 
  line as matrix from cte
where lvl=@level
order by r;
MATRIX
-------------------------
1 1 1 1 1 1 1 1 1 1 1
1 2 2 2 2 2 2 2 2 2 1
1 2 3 3 3 3 3 3 3 2 1
1 2 3 4 4 4 4 4 3 2 1
1 2 3 4 5 5 5 4 3 2 1
1 2 3 4 5 6 5 4 3 2 1
1 2 3 4 5 5 5 4 3 2 1
1 2 3 4 4 4 4 4 3 2 1
1 2 3 3 3 3 3 3 3 2 1
1 2 2 2 2 2 2 2 2 2 1
1 1 1 1 1 1 1 1 1 1 1

转载于:https://www.cnblogs.com/killkill/archive/2010/07/06/1772503.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值