文档首页 / SQL 写法示例

SQL 写法示例

按场景整理的 SQL 数据集写法:日期范围、可选条件、多选、分页、汇总、行级权限,附跨方言差异与常见错误。

概述

本文按任务给出可直接改用的 SQL 数据集写法,示例表为虚构的医院数据:

表 字段
outpatient_visit(门诊就诊) visit_id、patient_name、dept_code、doctor_account、visit_date、fee、status
department(科室) dept_code、dept_name、parent_code
orders(订单) order_no、customer_name、amount、status、create_time

语法规则见 SQL 参数与动态语法。示例中的报表参数需先在报表参数中声明(用「从SQL提取参数到报表参数」自动登记,再调整类型)。

功能入口

在 SQL 数据集 的 SQL 编辑区粘贴示例,也可在编辑器的「常用写法」对话框中复制内置示例。

操作步骤

  1. 选择与任务最接近的示例,改表名与字段名。
  2. 点击「从SQL提取参数到报表参数」,为每个参数选择类型。
  3. 用「数据预览」填参数验证,在「SQL 预览」标签页确认最终 SQL 与参数。

示例

日期范围

参数 startDate、endDate 为日期类型,右端用「小于」,避免遗漏结束日当天的时间部分:

SELECT visit_id, dept_code, visit_date, fee
FROM outpatient_visit
WHERE visit_date >= $startDate
  AND visit_date <  $endDate
ORDER BY visit_date DESC

最近 N 天,参数 days:

SELECT order_no, amount, create_time
FROM orders
WHERE create_time >= ${addDays(now(), -$days)}
  AND create_time <  ${now()}

可选条件

参数 deptCode 可空,minFee 为数值可空:

SELECT visit_id, dept_code, fee
FROM outpatient_visit
WHERE 1 = 1
  #{isEmpty($deptCode) ? '' : 'AND dept_code = $deptCode'}
  #{$minFee != null ? 'AND fee >= $minFee' : ''}

多选科室

deptCodes 类型选「集合」:

SELECT visit_id, dept_code, fee
FROM outpatient_visit
WHERE dept_code IN (${$deptCodes})

关键词模糊查询

SELECT visit_id, patient_name, dept_code
FROM outpatient_visit
WHERE patient_name LIKE ${'%' + $kw + '%'}

分组汇总

SELECT dept_code,
       COUNT(*)  AS visit_cnt,
       SUM(fee)  AS total_fee
FROM outpatient_visit
WHERE visit_date >= $startDate AND visit_date < $endDate
GROUP BY dept_code
HAVING SUM(fee) > 0
ORDER BY total_fee DESC

关联科室名称

SELECT v.visit_id, v.patient_name, d.dept_name, v.fee
FROM outpatient_visit v
LEFT JOIN department d ON d.dept_code = v.dept_code
WHERE v.visit_date >= $startDate AND v.visit_date < $endDate

行级权限:只看自己接诊的数据

SELECT visit_id, patient_name, fee
FROM outpatient_visit
WHERE doctor_account = ${userAccount()}

管理员看全部(isAdmin 为布尔参数):

SELECT visit_id, patient_name, fee
FROM outpatient_visit
WHERE 1 = 1
  #{$isAdmin == true ? '' : 'AND doctor_account = ${userAccount()}'}

引用系统自定义参数

「系统 > 自定义参数」中配置了 status,SQL 里要写成 ${$$config.status}:

SELECT order_no, amount, status
FROM orders
WHERE status = ${$$config.status}

手写分页

参数 pageNo(从 1 起)、pageSize。模板启用「数据浏览报表」时由系统分页,不要再手写。

数据库 写法
MySQL、MariaDB、PostgreSQL LIMIT $pageSize OFFSET ${($pageNo - 1) * $pageSize}
SQL Server OFFSET ${($pageNo - 1) * $pageSize} ROWS FETCH NEXT $pageSize ROWS ONLY
Oracle 三层嵌套,用 ROWNUM

MySQL 完整示例:

SELECT order_no, amount, create_time
FROM orders
WHERE status = $status
ORDER BY create_time DESC
LIMIT $pageSize OFFSET ${($pageNo - 1) * $pageSize}

Oracle 完整示例:

SELECT *
FROM (
    SELECT t.*, ROWNUM AS rn
    FROM (
        SELECT order_no, amount, create_time
        FROM orders
        WHERE status = $status
        ORDER BY create_time DESC
    ) t
    WHERE ROWNUM <= ${$pageNo * $pageSize}
)
WHERE rn > ${($pageNo - 1) * $pageSize}

按年分表

表名只能用 #{} 拼入。多语句正文必须 return:

SELECT order_no, amount, create_time
FROM #{
    var y = $year != null ? $year : year(now());
    return 'orders_' + y
}
WHERE status = 'completed'

公共表表达式

WITH dept_fee AS (
    SELECT dept_code, SUM(fee) AS total_fee
    FROM outpatient_visit
    WHERE visit_date >= $startDate AND visit_date < $endDate
    GROUP BY dept_code
)
SELECT d.dept_name, f.total_fee
FROM dept_fee f
JOIN department d ON d.dept_code = f.dept_code
ORDER BY f.total_fee DESC

注意事项

常见错误对照

错误写法 后果 正确写法
WHERE status = $$config.status 裸 $$config 不会被转换 ${$$config.status}
IN (#{$ids})、#{$list.map(...)} 拼集合 集合变成 [1, 2, 3],空集合变成 IN (),语法错误 参数类型选集合,写 IN (${$ids})
#{ var a = [...]; a.contains($f) ? $f : 'x' } 缺 return 拼出空串,ORDER BY 后为空 return a.contains($f) ? $f : 'x'
LIKE '%${$kw}%' 占位符在引号内,定义错误 LIKE ${'%' + $kw + '%'}
用 ${} 拼表名或子句 ${} 只绑定为 ?,值像 SQL 片段时报错「表达式看起来在生成动态 SQL 片段」 改用 #{} 并做白名单
WHERE a = 1; DELETE ... 中间分号被注入校验拒绝 只写一条查询

提示:跨库模板优先用 LIMIT n OFFSET m,MySQL 8、MariaDB、PostgreSQL 都支持;MySQL 的 LIMIT m, n 写法在 PostgreSQL 中不可用。

相关文档

联系我们

请填写您的信息,我们将在 1 个工作日内与您联系。