用SQL画字符画 (1/n)

这应该是一系列的文章, 主要用来记录用SQL画字符画, 以及自己对于SQL的理解. 内容可能也不仅仅是ASCII art,想到哪儿, 就写到哪儿

很多年前就知道T-SQL是图灵完备的, 这就意味着SQL能做很多数据操作以外的事情, 不仅仅是select from table.

2021年逛到这个网站, https://explainextended.com/, 看了代码, 有了用SQL画字符画的思路. 又正好是乔布斯逝世十周年的时候, SQL是图灵完备的想法再次涌现, 于是决定SQL画一个Apple logo, 也算是自己对乔老爷子的纪念

当然是从最基本的开始, 比如如何在SQL中画一个圆. 最终结果是这样子的 – 


整体的思路是把整个Result Panel 当做是平面坐标系. 每个字符代表一个坐标点, 是否显示当前字符, 取决于当前坐标点是否在圆的范围内

  • 生成需要的点
drop table if exists #row 
drop table if exists #col

declare @step decimal(38,5) = 0.05
; 
with r as ( --生成y轴坐标
	select n = cast(-1.0 as decimal(38,5))
	union all 
	select cast(n+@step as decimal(38,5))
	from r 
	where n+@step <= 1.0
) select * into #row from r 

go 

declare @step decimal(38,5) = 0.05
; with c as ( --生成x轴坐标
	select n = cast(-1.0 as decimal(38,5))
	union all 
	select cast(n+@step as decimal(38,5)) from c
	where n+@step <= 1.0
) select * into #col from c
  • 有了XY轴坐标, 我们只要根据圆的公式,把需要的点,*画出来, 不需要的点,用空格‘ ‘代替就行了
select 
rn = r.n
, symbol = case when power(r.n-0, 2)+ power(c.n-0, 2) <= 1 then '*'
		else ' ' 
	   end
from #row r, #col c

Q: 上面的代码形成的还是两列怎么变成一个平面呢?

A: cross join, 然后用string_agg + group by 就行了

with staging as 
( select 
	rn = r.n 
	, cn = c.n
	, symbol = case when power(r.n-0, 2)+ power(c.n-0, 2) <= 1 
                        then '*' 
			else ' '
	           end
  from #row r, #col c 
) 
select 
STRING_AGG(symbol, ' ') within group(order by cn) 
from staging 
group by rn option(maxrecursion 0)

上面的这段SQL就会生成一个圆形, 就像文章刚开始展示的那样.

下面一篇文章, 准备谈谈如何画出AppleLogo.

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *