Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在t-sql中按日期范围分组_Sql_Sql Server_Tsql - Fatal编程技术网

在t-sql中按日期范围分组

在t-sql中按日期范围分组,sql,sql-server,tsql,Sql,Sql Server,Tsql,我正在尝试对此表进行查询: 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

我正在尝试对此表进行查询:

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月的第三行感兴趣

我知道我可以在日期上使用min和max,在金额上使用sum,但我不知道如何用这种方式划分记录。
谢谢

如果你想做的只是看看钱什么时候开始流入,什么时候停止,这可能对你有用:

select 
    min(startdate),
    max(enddate),
    sum(amount)
where
    amount > 0
但这不包括没有资金流入的时期。

这里有一个想法:

;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)

虽然我认为,正如我写的那样,它假定Id是有序的。您可以用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

如果你不关心这段时间内的总数,而只想要从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))

感谢编辑马哈茂德·贾马尔。我试着从我的android手机上问这个问题。基于你想做什么分组?看起来你想把连续的零行和非零行分组,但是为什么不把五月行分开呢?他试图为数据创建三个切片-1没有钱进来2没有钱进来3没有钱进来。这两个干旱期将结束资金到达的时间。基于包括日期在内的金额为零和非零的日期。这将给你第一个开始日期、最后一个结束日期和总金额:是的,但正如OP所说:我想得到这个结果,这样我就能知道资金何时开始流入,何时停止,这是真的。减去前后的空周期,即:非常有用的查询。尽管这个函数返回的是介于两者之间的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))