在 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
希望这对您有所帮助,
里斯
让我先说说我的 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
希望这对您有所帮助,
里斯