SQL中每行多列数据求和及累计销售额列创建技术咨询
嘿,我来帮你搞定这两个SQL需求!下面分情况给你详细说明:
如果是要对同一行内的多个列进行求和,直接用加法运算符+就可以轻松实现。举个实际例子,假设你有一张包含各季度销售额的表quarterly_sales,列分别是q1_sales、q2_sales、q3_sales、q4_sales,要计算每行的年度总销售额:
SELECT q1_sales, q2_sales, q3_sales, q4_sales, q1_sales + q2_sales + q3_sales + q4_sales AS annual_total FROM quarterly_sales;
不过要注意,如果某列存在NULL值,直接相加会导致结果变成NULL。这时候可以用COALESCE()函数把NULL转为0,避免这个问题:
SELECT q1_sales, q2_sales, q3_sales, q4_sales, COALESCE(q1_sales, 0) + COALESCE(q2_sales, 0) + COALESCE(q3_sales, 0) + COALESCE(q4_sales, 0) AS annual_total FROM quarterly_sales;
这个需求用窗口函数就能完美解决,核心是SUM() OVER()语法,它可以在不分组的前提下,对指定范围内的行进行累计计算。
假设你的销售表sales_records包含sale_date(销售日期)和sales_units(销售单元数),要生成逐行递增的累计销售额列total_sales,可以这么写:
SELECT sale_date, sales_units, SUM(sales_units) OVER (ORDER BY sale_date) AS total_sales FROM sales_records ORDER BY sale_date;
这里的ORDER BY sale_date是关键,它确保累计是按照销售时间的先后顺序进行的。默认情况下,SUM() OVER(ORDER BY ...)的范围就是从第一行到当前行,所以可以不用额外写ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW(当然写上也没问题,更直观)。
如果你的数据需要按某个维度分组累计(比如按不同地区分组),只需要加上PARTITION BY子句即可:
SELECT region, sale_date, sales_units, SUM(sales_units) OVER (PARTITION BY region ORDER BY sale_date) AS total_sales_by_region FROM sales_records ORDER BY region, sale_date;
目前主流数据库(MySQL 8.0+、PostgreSQL、SQL Server、Oracle等)都支持窗口函数,要是你用的是非常老的数据库版本,可能需要用变量来实现,但窗口函数是最简洁高效的方案。
内容的提问来源于stack exchange,提问作者21Rahul

