[英]grouping by date range in t-sql
我正在嘗試對此表進行查詢:
Id startdate enddate amount
1 2013-01-01 2013-01-31 0.00
2 2013-02-01 2013-02-28 0.00
3 2013-03-01 2013-03-31 245
4 2013-04-01 2013-04-30 529
5 2013-05-01 2013-05-31 0.00
6 2013-06-01 2013-06-30 383
7 2013-07-01 2013-07-31 0.00
8 2013-08-01 2013-08-31 0.00
我想獲得輸出:
2013-01-01 2013-02-28 0
2013-03-01 2013-06-30 1157
2013-07-01 2013-08-31 0
我想得到這個結果,所以我會知道什么時候開始進貨,什么時候停止。 我也對錢開始進入之前的幾個月(第一行解釋)以及資金停止的月數感興趣(這也解釋了為什么我對2013年7月到2013年8月的第3行感興趣)。
我知道我可以在日期上使用最小值和最大值並總結金額,但我無法弄清楚如何將記錄划分為這種方式。
謝謝!
with CT as
(
select t1.*,
( select max(endDate)
from t
where startDate<t1.StartDate and SIGN(amount)<>SIGN(t1.Amount)
) as GroupDate
from t as t1
)
select min(StartDate) as StartDate,
max(EndDate) as EndDate,
sum(Amount) as Amount
from CT
group by GroupDate
order by StartDate
這是一個想法(也是一個小提琴 ):
;WITH MoneyComingIn AS
(
SELECT MIN(startdate) AS startdate, MAX(enddate) AS enddate,
SUM(amount) AS amount
FROM myTable
WHERE amount > 0
)
SELECT MIN(startdate) AS startdate, MAX(enddate) AS enddate,
SUM(amount) AS amount
FROM myTable
WHERE enddate < (SELECT startdate FROM MoneyComingIn)
UNION ALL
SELECT startdate, enddate, amount
FROM MoneyComingIn
UNION ALL
SELECT MIN(startdate) AS startdate, MAX(enddate) AS enddate,
SUM(amount) AS amount
FROM myTable
WHERE startdate > (SELECT enddate FROM MoneyComingIn)
第二,不使用UNION
( 小提琴 ):
SELECT MIN(startdate), MAX(enddate), SUM(amount)
FROM
(
SELECT startdate, enddate, amount,
CASE
WHEN EXISTS(SELECT 1
FROM myTable b
WHERE b.id>=a.id AND b.amount > 0) THEN
CASE WHEN EXISTS(SELECT 1
FROM myTable b
WHERE b.id<=a.id AND b.amount > 0)
THEN 2
ELSE 1
END
ELSE 3
END AS partition_no
FROM myTable a
) x
GROUP BY partition_no
雖然我認為正如所寫,它假定Id
是有序的。 您可以使用ROW_NUMBER() OVER(ORDER BY startdate)
替換它。
這樣的事情應該這樣做:
select min(startdate), max(enddate), sum(amount) from paiements
where enddate < (select min(startdate) from paiements where amount >0)
union
select min(startdate), max(enddate), sum(amount) from paiements
where startdate >= (select min(startdate) from paiements where amount >0)
and enddate <= (select max(enddate) from paiements where amount >0)
union
select min(startdate), max(enddate), sum(amount) from paiements
where startdate > (select max(enddate) from paiements where amount >0)
但對於這種報告,使用多個查詢可能更明確。
這樣做你想要的:
-- determine the three periods
DECLARE @StartMoneyIn INT
DECLARE @EndMoneyIn INT
SELECT @StartMoneyIn = MIN(Id)
FROM [Amounts]
WHERE amount > 0
SELECT @EndMoneyIn = MAX(Id)
FROM [Amounts]
WHERE amount > 0
-- retrieve the amounts
SELECT MIN(startdate) AS startdate, MAX(enddate) AS enddate, SUM(amount) AS amount
FROM [Amounts]
WHERE Id < @StartMoneyIn
UNION
SELECT MIN(startdate), MAX(enddate), SUM(amount)
FROM [Amounts]
WHERE Id >= @StartMoneyIn AND Id <= @EndMoneyIn
UNION
SELECT MIN(startdate), MAX(enddate), SUM(amount)
FROM [Amounts]
WHERE Id > @EndMoneyIn
如果你想做的就是看錢什么時候開始進來以及什么時候停止,這可能對你有用:
select
min(startdate),
max(enddate),
sum(amount)
where
amount > 0
這不包括沒有錢進入的時期。
如果您不關心期間的總數,但只想要從0到某事的記錄,反之亦然,您可以做一些像這樣的瘋狂事情:
select *
from MoneyTable mt
where exists ( select *
from MoneyTable mtTemp
where mtTemp.enddate = dateadd(day, -1, mt.startDate)
and mtTemp.amount <> mt.amount
and mtTemp.amount * mt.amount = 0)
或者,如果您必須包含第一條記錄:
select *
from MoneyTable mt
where exists ( select *
from MoneyTable mtTemp
where mtTemp.enddate = dateadd(day, -1, mt.startDate)
and mtTemp.amount <> mt.amount
and mtTemp.amount * mt.amount = 0 )
or not exists ( select *
from MoneyTable mtTemp
where mtTemp.enddate = dateadd(day, -1, mt.startDate))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.