我收到了一張包含事務列表的表。 的例子,可以說有4個領域: ID,用戶名,DateAddedd,金額SQL Server中的任何30天範圍內的數據(不是日期範圍內的)
在我想在運行30天來檢查,如果有一個時間的查詢,即,用戶進行的交易總數爲100或更多
我看到很多月份或一天的分組樣本,但問題是如果例如 用戶在20/4和5/5上做了50美元的交易另一個50美元的交易,查詢應該顯示它。 (在30天內100美元以上)
我收到了一張包含事務列表的表。 的例子,可以說有4個領域: ID,用戶名,DateAddedd,金額SQL Server中的任何30天範圍內的數據(不是日期範圍內的)
在我想在運行30天來檢查,如果有一個時間的查詢,即,用戶進行的交易總數爲100或更多
我看到很多月份或一天的分組樣本,但問題是如果例如 用戶在20/4和5/5上做了50美元的交易另一個50美元的交易,查詢應該顯示它。 (在30天內100美元以上)
我認爲這應該工作(我假設的交易有個約會組成部分,用戶可以在一天內有多個交易):
;with DailyTransactions as (
select UserID,DATEADD(day,DATEDIFF(day,0,DateAdded),0) as DateOnly,SUM(Amount) as Amount
from Transactions group by UserID,DATEADD(day,DATEDIFF(day,0,DateAdded),0)
), Numbers as (
select ROW_NUMBER() OVER (ORDER BY object_id) as n from sys.objects
), DayRange as (
select n from Numbers where n between 1 and 29
)
select
dt.UserID,dt.DateOnly as StartDate,MAX(ot.DateOnly) as EndDate, dt.Amount + COALESCE(SUM(ot.Amount),0) as TotalSpend
from
DailyTransactions dt
cross join
DayRange dr
left join
DailyTransactions ot
on
dt.UserID = ot.UserID and
DATEADD(day,dr.n,dt.DateOnly) = ot.DateOnly
group by dt.UserID,dt.DateOnly,dt.Amount
having dt.Amount + COALESCE(SUM(ot.Amount),0) >= 100.00
好的,我m使用3個公用表表達式。第一種(DailyTransactions)將交易表減少爲每天每個用戶一筆交易(如果DateAdded僅爲日期,並且每個用戶每天只有一筆交易,則不需要)。第二和第三(Numbers和DayRange)有點欺騙 - 我想讓我的數字1-29(用於DATEADD)。有多種方法可以創建一個永久的或(在這種情況下)臨時Numbers表。我只是選擇了一個,然後在DayRange中,我將其過濾爲我需要的數字。
既然我們有可用的東西,我們編寫主查詢。我們正在查詢DailyTransactions表中的行,但我們希望在同一個表中查找30天內的後續行。這就是DailyTransactions的左邊加入的內容。它找到後面的那些行,其中可能有0,1個或更多。如果它不止一個,我們希望將所有這些值加在一起,這就是爲什麼我們需要在這個階段進行更多的分組。最後,我們可以編寫我們的having條款,以僅過濾那些來自特定日期(dt.Amount
)的金額+來自晚些日期的金額總和(SUM(ot.Amount)
)符合您設定的標準的結果。
我此基礎上這樣定義的表:
create table Transactions (
UserID int not null,
DateAdded datetime not null,
Amount decimal (38,2)
)
如果我正確理解你,你需要一個日曆表,然後檢查日期和日期+ 30之間的總和。所以如果你想檢查一年的時間,你需要檢查一些像365週期的東西。
這是一種做法。遞歸CTE創建日曆,交叉應用計算CalDate和CalDate + 30之間每個CalDate的總和。
declare @T table(ID int, UserID int, DateAdded datetime, Amount money)
insert into @T values(1, 1, getdate(), 50)
insert into @T values(2, 1, getdate()-29, 60)
insert into @T values(4, 2, getdate(), 40)
insert into @T values(5, 2, getdate()-29, 50)
insert into @T values(7, 3, getdate(), 70)
insert into @T values(8, 3, getdate()-30, 80)
insert into @T values(9, 4, getdate()+50, 50)
insert into @T values(10,4, getdate()+51, 50)
declare @FromDate datetime
declare @ToDate datetime
select
@FromDate = min(dateadd(d, datediff(d, 0, DateAdded), 0)),
@ToDate = max(dateadd(d, datediff(d, 0, DateAdded), 0))
from @T
;with cal as
(
select @FromDate as CalDate
union all
select CalDate + 1
from cal
where CalDate < @ToDate
)
select S.UserID
from cal as C
cross apply
(select
T.UserID,
sum(Amount) as Amount
from @T as T
where T.DateAdded between CalDate and CalDate + 30
group by T.UserID) as S
where S.Amount >= 100
group by S.UserID
option (maxrecursion 0)
嘿的Mikael,感謝您的評論。我的問題是我沒有FromDate和ToDate變量。我需要一直從數據庫中獲取用戶在任何日期範圍內超過100美元的交易,只要這些日期的範圍爲30天 – Shay 2011-04-10 07:43:32
@Shay - FromDate和ToDate只是在那裏定義間隔你想檢查你是否想檢查整個表,你可以從表中獲取FromDate和ToDate。我會用那個更新答案。 – 2011-04-10 08:08:04
這可能是。儘管我現在看到了這個查詢,但我並不真正瞭解它。你能解釋一下你做了什麼嗎? – Shay 2011-04-10 07:46:51
@Shay - 我已添加一些評論 – 2011-04-10 07:56:14
謝謝達米安,輝煌! – Shay 2011-04-10 09:31:26