在select sql语句中按前一行增加值列

Posted

技术标签:

【中文标题】在select sql语句中按前一行增加值列【英文标题】:Increment value colum by previous row in select sql statement 【发布时间】:2013-06-05 13:58:08 【问题描述】:

我必须找到解决这个问题的方法......在这样的表中,我会看到我的列“C”在每一行上增加他的值,从一个常数开始,在列“B”中添加值和将同一列“C”中的前一个值相加。

此外...按用户分组。

例如:(起点Phil:350,起点Mark:100)

用户 - 点 - 初始点 菲尔 - 1000 - 1350 菲尔 - 150 - 1500 菲尔 - 200 - 1700 马克 - 300 - 400 马克 - 250 - 650

我该怎么做?

【问题讨论】:

你在使用 Luca 什么 RDBMS? 也贴表结构 你需要点菜:请问是什么? 起始值从何而来? 我使用的是 SQLSERVER 2008 R2;我将通过一个临时表获取起始值,(用户的 TotalSum 实际点)与我的另一个临时表与用户、点、日期、行号(部分按用户排序日期)结合在一起 【参考方案1】:

使用窗口。表声明是 SQL Server,但如果您的 RDBMS 支持,其余部分是标准 SQL(SQL Server 2012、PostgreSQL 9.1 等)

DECLARE @t TABLE (ID int IDENTITY(1,1), UserName varchar(100), Point int);

INSERT @t (UserName, Point)
VALUES
('Phil', 1000),
('Phil', 150),
('Phil', 200),
('Mark', 300),
('Mark', 250);

DECLARE @n TABLE (UserName varchar(100), StartPoint int);
INSERT @n (UserName, StartPoint)
VALUES
('Phil', 350),
('Mark', 100);

SELECT
    T.ID, T.UserName, T.Point,
    N.StartPoint + SUM(Point) OVER(PARTITION BY T.UserName ORDER BY T.ID ROWS UNBOUNDED PRECEDING)
FROM
    @n N
    JOIN
    @t T ON N.UserName = T.UserName
ORDER BY
    T.ID;

要做到这一点,你需要一个表的顺序(我使用了 ID)和一个更好的方法来做一个起始值(我使用了一个单独的表)

【讨论】:

Postgres 8.4 中已经引入了窗口函数,而不是 9.1(部分 SQL Server 2005 中也有) +1 。 . .该代码非常有用,即使答案不适用于 SQL Server 2008(可能在您发布此代码后添加到评论中)。【参考方案2】:

SQL Server 2008 不支持直接使用窗口函数的累积和。您可以使用相关子查询来获得相同的效果。

所以,使用与GBN相同的结构:

DECLARE @t TABLE (ID int IDENTITY(1,1), UserName varchar(100), Point int);

INSERT @t (UserName, Point)
VALUES
('Phil', 1000),
('Phil', 150),
('Phil', 200),
('Mark', 300),
('Mark', 250);

DECLARE @n TABLE (UserName varchar(100), StartPoint int);
INSERT @n (UserName, StartPoint)
VALUES
('Phil', 350),
('Mark', 100);

SELECT
    T.ID, T.UserName, T.Point,
    (N.StartPoint +
     (select SUM(Point) from @t t2 where t2.UserName = t.userName and t2.ID <= t.id)
    )
FROM
    @n N
    JOIN
    @t T ON N.UserName = T.UserName
ORDER BY
    T.ID;

【讨论】:

【参考方案3】:

您没有指定您的 DBMS,所以这是 ANSI SQL:

select "user",
       point,
       case 
         when "user" = 'Phil' then 350
         else 100
       end + sum(point) over (partition by "user" order by some_date_column) as sum
from the_table
where "user" in ('Mark', 'Phil')
order by "user", some_date_column;

您需要一些列来对行进行排序,否则“运行总和”将毫无意义,因为表中的行未排序(关系表中没有“第一行”之类的东西)。这就是我的示例中的some_date_column。只要它定义了正确的行顺序,它就可以是一个递增的主键或其他东西。

【讨论】:

以上是关于在select sql语句中按前一行增加值列的主要内容,如果未能解决你的问题,请参考以下文章

sql 字符串 排序

sql 查询语句自动增加序号

在 SQL 的 select 语句中使用 insert

根据两个文本列排序的 SQL 获取下一行和上一行

SQL:语句小记

SQL如何一次性添加多条记录