在HANA Data Studio中编写SQL游标实现数据集扩展需求
HANA SQL 生成扩展数据集:原始数据+全财季零年龄记录
需求说明
从原始数据集出发,保留原始数据的同时,为每个不同财季生成一份全用户、年龄设为0的记录,最终将所有结果合并。
输入样本数据集
| 姓名 | 年龄 | 财季(Fiscal_Quarter) |
|---|---|---|
| James | 22 | FY24Q1 |
| Henry | 32 | FY24Q2 |
| Ethan | 45 | FY24Q1 |
| Jake | 19 | FY24Q3 |
预期输出结果
| 姓名 | 年龄 | 财季(Fiscal_Quarter) |
|---|---|---|
| James | 22 | FY24Q1 |
| Henry | 32 | FY24Q2 |
| Ethan | 45 | FY24Q1 |
| Jake | 19 | FY24Q3 |
| James | 0 | FY24Q1 |
| Henry | 0 | FY24Q1 |
| Ethan | 0 | FY24Q1 |
| Jake | 0 | FY24Q1 |
| James | 0 | FY24Q2 |
| Henry | 0 | FY24Q2 |
| Ethan | 0 | FY24Q2 |
| Jake | 0 | FY24Q2 |
| James | 0 | FY24Q3 |
| Henry | 0 | FY24Q3 |
| Ethan | 0 | FY24Q3 |
| Jake | 0 | FY24Q3 |
方案一:集合式SQL(推荐,效率更高)
无需游标,利用交叉连接直接生成所需数据,性能远优于迭代式游标,适合绝大多数场景:
-- 假设原始表名为original_data WITH distinct_quarters AS ( -- 提取所有不同的财季 SELECT DISTINCT "财季(Fiscal_Quarter)" AS fiscal_qtr FROM original_data ) -- 合并原始数据和生成的零年龄数据 SELECT "姓名", "年龄", "财季(Fiscal_Quarter)" FROM original_data UNION ALL -- 为每个财季生成全用户零年龄记录 SELECT od."姓名", 0 AS "年龄", dq.fiscal_qtr AS "财季(Fiscal_Quarter)" FROM original_data od CROSS JOIN distinct_quarters dq -- 可选:按财季和姓名排序,和预期输出一致 ORDER BY "财季(Fiscal_Quarter)", "姓名";
方案说明
- 用CTE
distinct_quarters提取原始数据中所有不重复的财季; - 通过
CROSS JOIN将每个用户和每个财季配对,设置年龄为0; - 用
UNION ALL将原始数据和生成的零年龄数据合并。
方案二:游标实现(按需求迭代生成)
如果业务逻辑必须用游标迭代,可使用以下代码:
-- 创建临时表存储最终结果,ON COMMIT PRESERVE ROWS确保事务提交后数据保留 CREATE LOCAL TEMPORARY TABLE #result ( "姓名" NVARCHAR(50), "年龄" INTEGER, "财季(Fiscal_Quarter)" NVARCHAR(10) ) ON COMMIT PRESERVE ROWS; -- 先插入原始数据到结果表 INSERT INTO #result SELECT "姓名", "年龄", "财季(Fiscal_Quarter)" FROM original_data; -- 声明游标,获取所有不同财季 DECLARE cur_quarters CURSOR FOR SELECT DISTINCT "财季(Fiscal_Quarter)" AS fiscal_qtr FROM original_data; -- 声明变量存储当前遍历的财季 DECLARE v_fiscal_qtr NVARCHAR(10); -- 打开游标 OPEN cur_quarters; -- 遍历游标中的每个财季 FETCH NEXT cur_quarters INTO v_fiscal_qtr; WHILE SQLCODE = 0 DO -- 插入当前财季对应的全用户零年龄记录 INSERT INTO #result SELECT "姓名", 0 AS "年龄", v_fiscal_qtr AS "财季(Fiscal_Quarter)" FROM original_data; -- 获取下一个财季 FETCH NEXT cur_quarters INTO v_fiscal_qtr; END WHILE; -- 关闭游标 CLOSE cur_quarters; -- 查询最终结果 SELECT * FROM #result ORDER BY "财季(Fiscal_Quarter)", "姓名"; -- 可选:清理临时表 DROP TABLE #result;
方案说明
- 创建临时表存储最终结果;
- 先将原始数据插入临时表;
- 遍历所有不同财季,每次为当前财季生成全用户零年龄记录并插入临时表;
- 最后查询临时表得到最终结果。
内容的提问来源于stack exchange,提问作者Frankie Contreras
相关产品推荐
相关产品推荐

