AI 式文字编程写 SQL,不用大模型能做到什么程度?

Picture3png

简单的 SQL 本来看起来就像英语一样,算是一种文字式编程。比如,查订单表里金额大于 100 的订单:SELECT * FROM orders WHERE amount > 100

但当任务复杂时,需要用到 CTE、窗口函数等等,虽然还是那些英语关键字,写出来的 SQL 却越来越没法读了
比如这个需求,一张表记录多个账户的时间区间,区间之间有重叠,要把每个账户内相互重叠的区间合并成不相交的新区间。写出 SQL 是这样:

WITH t2 AS (
	SELECT
		account_id,
		start_date,
		end_date,
		MAX(end_date) OVER (
			PARTITION BY account_id
			ORDER BY
				CASE WHEN account_id IS NULL THEN 1 ELSE 0 END,
				account_id ASC,
				CASE WHEN start_date IS NULL THEN 1 ELSE 0 END,
				start_date ASC
			ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
		) AS prev_max
	FROM
		tb
),
t3 AS (
	SELECT
		account_id,
		start_date,
		end_date,
		prev_max,
		1 + SUM(
			CASE
				WHEN start_date > prev_max THEN 1
				ELSE 0
			END
		) OVER (
			PARTITION BY account_id
			ORDER BY
				CASE WHEN account_id IS NULL THEN 1 ELSE 0 END,
				account_id ASC,
				CASE WHEN start_date IS NULL THEN 1 ELSE 0 END,
				start_date ASC
		) AS gid
	FROM
		t2
)
SELECT
	account_id,
	MIN(start_date) AS start_date,
	MAX(end_date) AS end_date
FROM
	t3
GROUP BY
	account_id,
	gid
ORDER BY
	account_id,
	start_date;

其实,我们只要给 SQL 增加分步的机制,再补充一些能处理有序运算(窗口函数)的动作,复杂的 SQL 也可以像自然语言一样读写了。
SQLazy 就是这样:把复杂逻辑拆成步骤,每一步都还是简单 SQL 那种人人都看得懂的文字。
比如刚才那个任务写出来是四步:

t1=tb: 排序 account_id, start_date
t2=计算列 最大, end_date[:-1], 命名 prev_max; 分区 account_id
t3=分段 条件 start_date>prev_max 命名 gid; 分区 account_id
t4=汇总 最小 start_date 命名 start_date, 最大 end_date 命名 end_date; 分组 account_id, gid

每一步都是大白话,先排序、再算前面的最大结束日、按条件分段、最后汇总合并。写起来很轻松,过两个月看也能秒懂。
但这个怎么执行?把它交给 SQLazy 编译器,上面的 SQL 就出来了:
同一份逻辑,编译一百次也是同一份 SQL,没概率,没幻觉。
SQLazy 并不能用完全灵活的自然语言,它和 SQL 一样,语句也有一定的规范。但无论如何,不用大模型的文字编程也能写出这么复杂的 SQL 了
如果有大模型配合就会更方便,LLM 可以把口语化的自然语言翻译成符合 SQLazy 规范的文字语句,这样很容易审计了。AI 甚至还能把复杂任务拆解直接写出 SQLazy 的多步语句,然后当场调试确认,最后编译成 SQL,再也不用担心 AI 的幻觉。