如何在SQL Server中编写类似Oracle MULTISET的SELECT查询?
SQL Server 实现类似Oracle MULTISET的查询方案及Web服务返回最佳实践
先明确你的场景和需求:
原始数据表
T_WORK表
| Work_id | Cre_d |
|---|---|
| 1 | 2016 |
| 2 | 2017 |
| 3 | 2018 |
T_WORK_PARAM表
| Work_id | Param_nm | Param_val |
|---|---|---|
| 1 | Name | John |
| 1 | Place | London |
| 1 | Date | 01-01-2018 |
| 2 | Name | Trump |
| 2 | Place | Newyork |
| 2 | Date | 02-02-2018 |
期望输出格式
| Name | John | |
|---|---|---|
| 1 | Place | London |
| Date | 01-01-2018 | |
| ----- | ------- | ------------ |
| Name | Trump | |
| 2 | Place | Newyork |
| Date | 02-02-2018 |
一、SQL Server中直接生成期望格式的查询
如果是要生成你展示的那种Work_id仅在组内首行显示的结果,可以用ROW_NUMBER()窗口函数来控制Work_id的显示:
SELECT -- 仅在每组第一行显示Work_id,其余行留空 CASE WHEN ROW_NUMBER() OVER(PARTITION BY T1.Work_id ORDER BY T2.Param_nm) = 1 THEN CAST(T1.Work_id AS VARCHAR(10)) ELSE '' END AS Work_id, T2.Param_nm, T2.Param_val FROM T_WORK T1 INNER JOIN T_WORK_PARAM T2 ON T1.Work_id = T2.Work_id ORDER BY T1.Work_id, T2.Param_nm;
这个查询会直接输出你想要的那种格式化结果,分组后的Work_id只在第一条记录显示,后续同组记录的Work_id列为空。
二、类似Oracle MULTISET的嵌套结果实现
如果是想要像Oracle那样返回每行Work_id关联一组参数记录的结构化结果(更适合Web服务接收),SQL Server可以用FOR JSON PATH来生成JSON格式的嵌套数据,这是Web服务场景下的常用方案:
SELECT T1.Work_id, -- 将当前Work_id对应的所有参数转为JSON数组 (SELECT Param_nm, Param_val FROM T_WORK_PARAM T2 WHERE T2.Work_id = T1.Work_id FOR JSON PATH) AS Parameters FROM T_WORK T1;
返回的结果示例如下:
| Work_id | Parameters |
|---|---|
| 1 | [{"Param_nm":"Name","Param_val":"John"},{"Param_nm":"Place","Param_val":"London"},{"Param_nm":"Date","Param_val":"01-01-2018"}] |
| 2 | [{"Param_nm":"Name","Param_val":"Trump"},{"Param_nm":"Place","Param_val":"Newyork"},{"Param_nm":"Date","Param_val":"02-02-2018"}] |
| 3 | NULL |
这种JSON格式的数据非常容易被Web服务解析和处理,前端可以根据需要将其渲染成你想要的表格样式。
三、无法直接实现时的Web服务最佳实践
如果你的场景中直接生成格式化表格有困难(比如复杂的分组展示需求),最佳的常规方式是:
- 后端返回结构化数据:比如用上面的JSON格式,或者XML格式,将Work_id和对应的参数集合完整返回,不做显示层面的格式化。
- 前端负责展示格式化:Web服务的调用方(前端页面或客户端)接收到结构化数据后,通过代码逻辑实现分组显示,控制Work_id仅在每组首行展示,其余行留空。
这种前后端分离的方式更符合现代Web开发的最佳实践,后端专注于数据提供,前端专注于用户展示,也更易于维护和扩展。
内容的提问来源于stack exchange,提问作者Kishor Kumar
相关产品推荐
相关产品推荐

