在 sql 服务器中使用循环语句创建 Sum 函数

Create Sum Function with loop statement in sql server

让我先说说我的 table ;

这3个table是主要的table。

俱乐部个人资料我的客户信息存在,在卡交易中我的客户交易存在并且 cardtransationslog 交易详细信息存在。

这是我的查询逻辑: select 人总积分和 select dateTime(卡交易日志)当他们的积分超过 12000

我试过这个查询,但我不能select 3th table

的时间
SELECT CP.ClubProfileId, FirstName , LastName ,
sum(Points)
FROM ClubProfile CP JOIN CardTransaction CT 
ON CT.ClubProfileId = CP.ClubProfileId
JOIN CardTransactionLog CL
ON CL.CardTransactionLogId = CT.CardTransactionLogId
group by FirstName,LastName,cp.ClubProfileId
having sum(Points) > 12000

我的主要问题是,在上面的查询中,当人们的总分超过 120000 时,我找不到他们的时间

换句话说select他们积分超过12000的时候

如果包含在适当的聚合函数(如 MIN 或 MAX)中,您可以轻松地从卡交易 table 中获取日期时间。

SELECT CP.ClubProfileId, FirstName , LastName , max(CT.dateTime) as MaxDateTime
sum(Points)
FROM ClubProfile CP JOIN CardTransaction CT 
ON CT.ClubProfileId = CP.ClubProfileId
JOIN CardTransactionLog CL
ON CL.CardTransactionLogId = CT.CardTransactionLogId
group by FirstName,LastName,cp.ClubProfileId
having sum(Points) > 12000

如果您不想要最小值(最早)或最大值(最晚),您需要在问题中提供更多信息。

编辑

问题其实是"find the dateTime when the points total exceeds 12,000"。为了找到这个,我们需要某种 运行 总点数。 SQLPerformance.com 文章 Best approaches for running totals 表明游标通常比 运行 总数的基于集合的方法更有效,因此这里是一个基于游标的解决方案。

create table dbo.ClubProfile (
ClubProfileId int not null,
FirstName varchar(10) not null,
LastName varchar(10) not null
)

create table dbo.CardTransaction (
ClubProfileId int not null,
CardTransactionLogId int not null,
Points int not null
)

create table dbo.CardTransactionLog (
CardTransactionLogId int not null,
[dateTime] datetime not null
)

insert dbo.ClubProfile values (1,'Rhys','Jones')
insert dbo.CardTransaction values (1, 1, 11000)
insert dbo.CardTransaction values (1, 2, 2000)
insert dbo.CardTransaction values (1, 3, 2000)
insert dbo.CardTransactionLog values (1, '2015-01-16')
insert dbo.CardTransactionLog values (2, '2015-01-17')
insert dbo.CardTransactionLog values (3, '2015-01-18')
go

-- create a working table to hold the dateTime and running sum of points for each ClubProfile
if (object_id('tempdb..#workingTable') is not null) drop table #workingTable
select ClubProfileId, cast(null as datetime) as dateTime, cast(0 as int) as SumPoints
    into #workingTable
    from dbo.ClubProfile

-- declare a cursor to iterate over all of the transactions.
declare cur cursor local static forward_only read_only for
    select CT.ClubProfileId, CT.Points, CL.dateTime
    from dbo.CardTransaction CT
    inner join dbo.CardTransactionLog CL on CL.CardTransactionLogId = CT.CardTransactionLogId
    order by CL.dateTime -- make sure this is the right order for your requirements

declare @ClubProfileId int
declare @Points int
declare @dateTime datetime

open cur
fetch next from cur into @ClubProfileId, @Points, @dateTime

while (@@fetch_status = 0)
begin

    -- Update the working table with the current date and running sum of points
    -- if the current running sum of points is less than 12,000.
    update #workingTable set
        [dateTime] = @dateTime,
        SumPoints = SumPoints + @Points
    where
        ClubProfileId = @ClubProfileId and
        SumPoints < 12000 -- do you want "<" or "<="?

    fetch next from cur into @ClubProfileId, @Points, @dateTime
end

close cur
deallocate cur

-- select the results, note that SumPoints here is only the partial sum upto exceeding 12,000
select
    CP.ClubProfileId, CP.FirstName, CP.LastName, T.dateTime, T.SumPoints
from
    dbo.ClubProfile CP
        inner join #workingTable T on T.ClubProfileId = CP.ClubProfileId

希望这对您有所帮助,

里斯