问题来源于此贴:如何通过定时任务写入的扩展表数据,最大值成功获取。 – 服务中心


这里对解决方法做一记录,方便日后使用
📌 两种场景的区别
| 场景 | 描述 | 使用函数 |
|---|---|---|
| 行内最大值 | 同一行的多列之间比较 | GREATEST() |
| 跨行最大值 | 多行之间比较(聚合) | MAX() |
| 多行多列最大值 | 整个表或多个列的多行数据中找最大值 | 组合使用 |
🔍 多行多列求最大值的几种方案
方案一:整个表中多列所有行的最大值
如果你想找出整个表中 Col1、Col2、Col3 所有数据的最大值:
SELECT MAX(AllValues) AS GlobalMax
FROM (
SELECT Col1 AS AllValues FROM YourTable
UNION ALL
SELECT Col2 FROM YourTable
UNION ALL
SELECT Col3 FROM YourTable
) AS Tmp;
转化到WorkFine内,使用组合视图然后使用最大值(MAX)函数取值
或者使用 VALUES(更简洁):
SELECT MAX(Val) AS GlobalMax
FROM YourTable
CROSS APPLY (VALUES (Col1), (Col2), (Col3)) AS Tmp(Val);
方案二:按分组求多行多列的最大值
如果你需要按某个字段分组,每组内求多列的最大值:
SELECT
GroupCol,
MAX(Val) AS GroupMax
FROM YourTable
CROSS APPLY (VALUES (Col1), (Col2), (Col3)) AS Tmp(Val)
GROUP BY GroupCol;
方案三:先求行内最大值,再求跨行最大值
分两步:先用 GREATEST 求每行的最大值,再用 MAX 求所有行的最大值。
GREATEST函数需要SQL Server为2022+版本
-- SQL Server 2022+
SELECT MAX(GREATEST(Col1, Col2, Col3)) AS GlobalMax
FROM YourTable;
-- SQL Server 2019 及更早版本
SELECT MAX(RowMax) AS GlobalMax
FROM (
SELECT
(SELECT MAX(Val) FROM (VALUES (Col1), (Col2), (Col3)) AS Tmp(Val)) AS RowMax
FROM YourTable
) AS SubQuery;
📊 完整示例对比
假设表数据如下:
| ID | Col1 | Col2 | Col3 |
|---|---|---|---|
| 1 | 10 | 25 | 15 |
| 2 | 30 | 5 | 20 |
| 3 | 8 | 12 | 50 |
-- 1. 每行的最大值(行内)
SELECT ID, GREATEST(Col1, Col2, Col3) AS RowMax FROM YourTable;
-- 结果:1→25, 2→30, 3→50
-- 2. 整个表所有列的最大值(跨行+跨列)
SELECT MAX(Val) AS GlobalMax
FROM YourTable
CROSS APPLY (VALUES (Col1), (Col2), (Col3)) AS Tmp(Val);
-- 结果:50
-- 3. 先求行内最大,再求跨行最大
SELECT MAX(GREATEST(Col1, Col2, Col3)) AS GlobalMax FROM YourTable;
-- 结果:50
✅ 总结
| 需求 | 推荐方法 |
|---|---|
| 同行多列最大值 | GREATEST(Col1, Col2, Col3) |
| 单列跨行最大值 | MAX(Col1) |
| 多行多列全局最大值 | CROSS APPLY + VALUES + MAX 或 MAX(GREATEST(...)) |
| 分组后多行多列最大值 | CROSS APPLY + VALUES + GROUP BY |
核心区别:
GREATEST= 横向比较(同一行,多列)MAX= 纵向比较(同一列,多行)- 多行多列 = 先横向再纵向,或先转成单列再纵向聚合
PS:最小值也是同理的
📌 CASE 表达式是同行比较(行内比较)
📌 CASE 表达式是同行比较(行内比较)
CASE 表达式方法:
SELECT
列1,
列2,
列3,
CASE
WHEN 列1 >= 列2 AND 列1 >= 列3 THEN 列1
WHEN 列2 >= 列3 THEN 列2
ELSE 列3
END AS 行最大值
FROM 数据表;
这是同行比较
| 特征 | 说明 |
|---|---|
| 比较范围 | 同一行内的 列1、列2、列3 |
| 返回结果 | 每行返回一个最大值 |
| 是否聚合 | ❌ 没有使用聚合函数 |
| 是否有 GROUP BY | ❌ 没有分组 |
结果示例
假设表数据如下:
| 编号 | 列1 | 列2 | 列3 |
|---|---|---|---|
| 1 | 10 | 25 | 15 |
| 2 | 30 | 5 | 20 |
| 3 | 8 | 12 | 50 |
CASE 表达式输出:
| 编号 | 列1 | 列2 | 列3 | 行最大值 |
|---|---|---|---|---|
| 1 | 10 | 25 | 15 | 25 |
| 2 | 30 | 5 | 20 | 30 |
| 3 | 8 | 12 | 50 | 50 |
👉 每行独立计算,返回该行的最大值。
如果要全部数据内比较(跨行+跨列)
需要在外层再包一层 MAX() 聚合函数:
-- 方法:先求每行最大,再求全局最大
SELECT MAX(行最大值) AS 全局最大值
FROM (
SELECT
CASE
WHEN 列1 >= 列2 AND 列1 >= 列3 THEN 列1
WHEN 列2 >= 列3 THEN 列2
ELSE 列3
END AS 行最大值
FROM 数据表
) AS 子查询;
输出:
| 全局最大值 |
|---|
| 50 |
👉 整个表所有行、所有列中的最大值(只有一个结果)。
快速区分
| 代码特征 | 比较类型 | 结果数量 |
|---|---|---|
CASE ... END 直接在 SELECT 中 | 同行比较 | 每行一个结果 |
MAX(CASE ... END) 或外层包 MAX() | 全部数据比较 | 单个结果 |
GREATEST(列1, 列2, 列3) | 同行比较 | 每行一个结果 |
MAX(GREATEST(...)) | 全部数据比较 | 单个结果 |
总结
| 方法 | 默认行为 | 如何改为全局比较 |
|---|---|---|
| CASE 表达式 | 同行比较 | 外层加 MAX() |
| GREATEST 函数 | 同行比较 | 外层加 MAX() |
| VALUES + MAX | 可同行可全局 | 看是否加 GROUP BY |
所以,CASE 表达式默认是同行比较,如果需要全部数据内比较,需要在外层再使用聚合函数 MAX()。
相关文章
© 版权声明
THE END















