最保险的通用写法是 SELECT ... FROM (VALUES (...)) AS t(...)。VALUES 构造单行虚拟数据最轻量且跨库兼容性好;系统伪表如 sysibm.sysdummy1 或 spt_values 可避免建表;PostgreSQL 支持无 FROM 的标量表达式,而 SQL Server 和 Teradata 不支持。
可以直接用 SELECT 调用函数,配合 VALUES 或空表(如 sysibm.sysdummy1、master..spt_values)或常量表达式,完全不依赖业务表。
VALUES 构造单行虚拟数据测试函数这是最轻量、跨库兼容性最好的方式,尤其适合验证字符串、数学、日期类函数行为。SQL 标准支持 VALUES 作为独立语句返回结果集,无需 FROM 子句。
VALUES 后跟括号内表达式,会自动推导列名和类型,比如 VALUES (MAX(1,5,3)) 返回单列单行SELECT MAX(a) FROM (VALUES (1),(5),(3)) AS t(a);但更简洁写法是:SELECT (SELECT MAX(x) FROM (VALUES (1),(5),(3)) AS v(x))
VALUES,改用 SELECT MAX(x) FROM (VALUES (1),(5),(3)) AS t(x) 即可——注意必须显式别名 AS t(x)
VALUES ROW(1), ROW(5), ROW(3),但 MAX() 是聚合函数,仍需 SELECT MAX(col) FROM (VALUES ...) 结构sysibm.sysdummy1、master..spt_values)避免建表某些数据库提供只读单行伪表,本质是“占位符”,专为无表场景设计,调用零开销。
SELECT MAX(10, 20, 30) FROM sysibm.sysdummy1 ——sysdummy1 恒有一行,允许在无真实表时执行标量函数SELECT GETDATE(), LEN('hello') FROM master..spt_values WHERE number = 0,但更稳妥的是 SELECT TOP 1 GETDATE(), LEN('hello') FROM sys.objects(任意系统视图都行,只要不加 WHERE 条件就可能返回多行;加 TOP 1 确保稳定)SELECT NOW(), UPPER('test'); 直接写——它允许无 FROM 的标量表达式SELECT MAX() FROM dual(Oracle 风格),SQL Server 和 Teradata 没有 dual 表DECLARE + SELECT 测试标量函数(SQL Server 专用)当函数接受参数且你想控制输入组合时,变量赋值比构造虚拟表更直观,尤其适合边界值验证。
DECLARE @a INT = 10, @b INT = -5, @c INT = 0;
SELECT 调用函数:SELECT ABS(@a), SIGN(@b), ISNULL(@c, 999);
MAX(),仍需转成子查询形式:SELECT (SELECT MAX(x) FROM (VALUES (@a),(@b),(@c)) AS v(x))
FROM 子句中,仍需搭配 VALUES 或临时表真正容易被忽略的点是:不同数据库对“无 FROM 的 SELECT”支持程度差异极大。PostgreSQL 允许,SQL Server 不允许(会报 Incorrect syntax near 'SELECT'),Teradata 要求至少一个表或 sysdummy1。所以最保险的通用写法,永远是 SELECT ... FROM (VALUES (...)) AS t(...)——它明确表达了“我只想要计算,不碰任何业务数据”。