how to replace "Nothing" cell by last month value - sql-server-2005

I am using SSRS develop a report via Matrix.
I sum the product sales qty every month but if some month sale qty is 0, the cell will be Nothing.
I'm trying to using Previous function to solve problem but this function seems not work for Matrix object.
Is there any way to do this?
1st table is currently report result.
2nd table is that i want.

Assuming that you have a table with the structure and content like this:
CREATE TABLE a (date Date, product_name NVarchar(20), sale_qty Decimal(10,2))
INSERT INTO a (date, product_name, sale_qty) VALUES ('20130510','product A',1)
INSERT INTO a (date, product_name, sale_qty) VALUES ('20130601','product A',0)
INSERT INTO a (date, product_name, sale_qty) VALUES ('20130501','product B',5)
INSERT INTO a (date, product_name, sale_qty) VALUES ('20140205','product A',1)
INSERT INTO a (date, product_name, sale_qty) VALUES ('20140215','product A',1)
INSERT INTO a (date, product_name, sale_qty) VALUES ('20140202','product B',2)
INSERT INTO a (date, product_name, sale_qty) VALUES ('20140301','product A',0)
Then the below sql-statement will work for you (as far as I understood the requirement):
SELECT
y.Date2 AS 'yyyy/mm'
, y.product_name
, ISNULL(z.Month_sale_QTY,0) AS Month_sale_QTY
FROM
(SELECT
DATEADD(MONTH, x.number, y.StartDate) AS Date2
, (SELECT TOP 1 DATEADD(d,1-DATEPART(d,a.date),a.date) FROM a WHERE DATEADD(d,1-DATEPART(d,a.date),a.date) <= DATEADD(MONTH, x.number, y.StartDate) AND a.product_name = p.product_name AND ISNULL(a.sale_qty,0)<>0 ORDER BY 1 DESC) AS Date3
, p.product_name
FROM
master.dbo.spt_values x
INNER JOIN
(SELECT Dateadd(d,1-DATEPART(d, MIN(Date)), MIN(Date)) AS StartDate, MAX(Date) AS EndDate FROM a) AS y
ON x.number <= DATEDIFF(MONTH, y.StartDate, y.EndDate)
,(SELECT DISTINCT product_name FROM a) AS p WHERE x.type = 'P') y
LEFT JOIN
(SELECT
DATEADD(d,1-DATEPART(d,a.date),a.date) AS Date2
, a.product_name
, SUM(a.sale_qty) as Month_sale_QTY
FROM a
GROUP BY
DATEADD(d,1-DATEPART(d,a.date),a.date)
, a.product_name
) z ON y.Date3 = z.Date2 AND y.product_name = z.product_name
It returns the following:
yyyy/mm product_name Month_sale_QTY
---------- -------------------- ---------------------------------------
2013-05-01 product A 1.00
2013-06-01 product A 1.00
2013-07-01 product A 1.00
2013-08-01 product A 1.00
2013-09-01 product A 1.00
2013-10-01 product A 1.00
2013-11-01 product A 1.00
2013-12-01 product A 1.00
2014-01-01 product A 1.00
2014-02-01 product A 2.00
2014-03-01 product A 2.00
2013-05-01 product B 5.00
2013-06-01 product B 5.00
2013-07-01 product B 5.00
2013-08-01 product B 5.00
2013-09-01 product B 5.00
2013-10-01 product B 5.00
2013-11-01 product B 5.00
2013-12-01 product B 5.00
2014-01-01 product B 5.00
2014-02-01 product B 2.00
2014-03-01 product B 2.00
I'm sure it can be optimized using windowing functions and/or CTE, but as a quick solution this one will work too.

Related

Given two date ranged discount tables and product price, calculate date ranged final price

I have two tables with seasonal discounts. In each of these two tables are non overlapping date ranges, product id and discount that applies in that date range. Date ranges from one table however may overlap with date ranges in the other table. Given a third table with product id and its default price, the goal is to efficiently calculate seasonal - date ranged prices for product id after discounts from both tables have been applied.
Discounts multiply only in their overlapping period, e.g. if a first discount is 0.9 (10%) from 2019-07-01 to 2019-07-30, and a second discount is 0.8 from 2019-07-16 to 2019-08-15, this translates to: 0.9 discount from 2019-07-01 to 2019-07-15, 0.72 discount from 2019-07-16 to 2019-07-30, and 0.8 discount from 2019-07-31 to 2019-08-15.
I have managed to come to a solution, by first generating a table that holds ordered all of start and end dates in both discount tables, then generating a resulting table of all smallest disjoint intervals, and then for each interval, generating all prices, default, price with only the discount from first table applied (if any applies), price with only the discount from second table applied (if any applies), price with both discounts applied (if so possible) and then taking a min of these four prices. See sample code bellow.
declare #pricesDefault table (product_id int, price decimal)
insert into #pricesDefault
values
(1, 100),
(2, 120),
(3, 200),
(4, 50)
declare #discountTypeA table (product_id int, modifier decimal(4,2), startdate datetime, enddate datetime)
insert into #discountTypeA
values
(1, 0.75, '2019-06-06', '2019-07-06'),
(1, 0.95, '2019-08-06', '2019-08-20'),
(1, 0.92, '2019-05-06', '2019-06-05'),
(2, 0.75, '2019-06-08', '2019-07-19'),
(2, 0.95, '2019-07-20', '2019-09-20'),
(3, 0.92, '2019-05-06', '2019-06-05')
declare #discountTypeB table (product_id int, modifier decimal(4,2), startdate datetime, enddate datetime)
insert into #discountTypeB
values
(1, 0.85, '2019-06-20', '2019-07-03'),
(1, 0.65, '2019-08-10', '2019-08-29'),
(1, 0.65, '2019-09-10', '2019-09-27'),
(3, 0.75, '2019-05-08', '2019-05-19'),
(2, 0.95, '2019-05-20', '2019-05-21'),
(3, 0.92, '2019-09-06', '2019-09-09')
declare #pricingPeriod table(product_id int, discountedPrice decimal, startdate datetime, enddate datetime);
with allDates(product_id, dt) as
(select distinct product_id, dta.startdate from #discountTypeA dta
union all
select distinct product_id, dta.enddate from #discountTypeA dta
union all
select distinct product_id, dtb.startdate from #discountTypeB dtb
union all
select distinct product_id, dtb.enddate from #discountTypeB dtb
),
allproductDatesWithId as
(select product_id, dt, row_number() over (partition by product_id order by dt asc) 'Id'
from allDates),
sched as
(select pd.product_id, apw1.dt startdate, apw2.dt enddate
from #pricesDefault pd
join allproductDatesWithId apw1 on apw1.product_id = pd.product_id
join allproductDatesWithId apw2 on apw2.product_id = pd.product_id and apw2.Id= apw1.Id+1
),
discountAppliedTypeA as(
select sc.product_id, sc.startdate, sc.enddate,
min(case when sc.startdate >= dta.startdate and dta.enddate >= sc.enddate then pd.price * dta.modifier else pd.price end ) 'price'
from sched sc
join #pricesDefault pd on pd.product_id = sc.product_id
left join #discountTypeA dta on sc.product_id = dta.product_id
group by sc.product_id, sc.startdate , sc.enddate ),
discountAppliedTypeB as(
select daat.product_id, daat.startdate, daat.enddate,
min(case when daat.startdate >= dta.startdate and dta.enddate >= daat.enddate then daat.price * dta.modifier else daat.price end ) 'price'
from discountAppliedTypeA daat
left join #discountTypeB dta on daat.product_id = dta.product_id
group by daat.product_id, daat.startdate , daat.enddate )
select * from discountAppliedTypeB
order by product_id, startdate
Calculating a min of all possible prices is unnecessary overhead. I'd like to generate, just one resulting price and have it as a final price.
Here is the resulting set:
product_id start_date end_date final_price
1 2019-05-06 00:00:00.000 2019-06-05 00:00:00.000 92.0000
1 2019-06-05 00:00:00.000 2019-06-06 00:00:00.000 100.0000
1 2019-06-06 00:00:00.000 2019-06-20 00:00:00.000 75.0000
1 2019-06-20 00:00:00.000 2019-07-03 00:00:00.000 63.7500
1 2019-07-03 00:00:00.000 2019-07-06 00:00:00.000 75.0000
1 2019-07-06 00:00:00.000 2019-08-06 00:00:00.000 100.0000
1 2019-08-06 00:00:00.000 2019-08-10 00:00:00.000 95.0000
1 2019-08-10 00:00:00.000 2019-08-20 00:00:00.000 61.7500
1 2019-08-20 00:00:00.000 2019-08-29 00:00:00.000 65.0000
1 2019-08-29 00:00:00.000 2019-09-10 00:00:00.000 100.0000
1 2019-09-10 00:00:00.000 2019-09-27 00:00:00.000 65.0000
2 2019-05-20 00:00:00.000 2019-05-21 00:00:00.000 114.0000
2 2019-05-21 00:00:00.000 2019-06-08 00:00:00.000 120.0000
2 2019-06-08 00:00:00.000 2019-07-19 00:00:00.000 90.0000
2 2019-07-19 00:00:00.000 2019-07-20 00:00:00.000 120.0000
2 2019-07-20 00:00:00.000 2019-09-20 00:00:00.000 114.0000
3 2019-05-06 00:00:00.000 2019-05-08 00:00:00.000 184.0000
3 2019-05-08 00:00:00.000 2019-05-19 00:00:00.000 138.0000
3 2019-05-19 00:00:00.000 2019-06-05 00:00:00.000 184.0000
3 2019-06-05 00:00:00.000 2019-09-06 00:00:00.000 200.0000
3 2019-09-06 00:00:00.000 2019-09-09 00:00:00.000 184.0000
Is there a more efficient to this solution that I am not seeing?
I have a large data set of ~20K rows in real product prices table, and 100K- 200K rows in both discount tables.
Indexing structure of the actual tables is following: product id is clustered index in product prices table, whilst discount tables have an Id surrogate column as clustered index (as well as primary key), and (product_id, start_date, end_date) as a non clustered index.
You can generate the dates using union. Then bring in all discounts that are valid on that date, and calculate the total.
This looks like:
with prices as (
select a.product_id, v.dte
from #discountTypeA a cross apply
(values (a.startdate), (a.enddate)) v(dte)
union -- on purpose to remove duplicates
select b.product_id, v.dte
from #discountTypeB b cross apply
(values (b.startdate), (b.enddate)) v(dte)
),
p as (
select p.*, 1-a.modifier as a_discount, 1-b.modifier as b_discount, pd.price
from prices p left join
#pricesDefault pd
on pd.product_id = p.product_id left join
#discountTypeA a
on p.product_id = a.product_id and
p.dte >= a.startdate and p.dte < a.enddate left join
#discountTypeb b
on p.product_id = b.product_id and
p.dte >= b.startdate and p.dte < b.enddate
)
select p.product_id, price * (1 - coalesce(a_discount, 0)) * (1 - coalesce(b_discount, 0)) as price, a_discount, b_discount,
dte as startdate, lead(dte) over (partition by product_id order by dte) as enddate
from p
order by product_id, dte;
Here is a db<>fiddle.
Here is a version that works out the price for every date. You can then either use this directly, or use one of the many solutions on SO for working out date ranges.
In this example I have hard coded the date limits, but you could easily read them from your tables if you prefer.
I haven't done any performance testing on this, but give it a go. Its quite a bit simpler do if you have the right indexes it might be quicker.
;with dates as (
select convert(datetime,'2019-05-06') as d
union all
select d+1 from dates where d<'2019-09-27'
)
select pricesDefault.product_id, d, pricesDefault.price as baseprice,
discountA.modifier as dA,
discountB.modifier as dB,
pricesDefault.price*isnull(discountA.modifier,1)*isnull(discountB.modifier,1) as finalprice
from #pricesDefault pricesDefault
cross join dates
left join #discountTypeA discountA on discountA.product_id=pricesDefault.product_id and d between discountA.startdate and discountA.enddate
left join #discountTypeB discountB on discountB.product_id=pricesDefault.product_id and d between discountB.startdate and discountB.enddate
order by pricesDefault.product_id, d
Option (MaxRecursion 1000)

SQL Server 2012 Find bucket wise products and dates

I have a table like below:
date prodname
2018-01-01 Product1
2018-01-05 Product1
2018-01-09 Product1
2018-01-17 Product1
2018-01-24 Product1
2018-01-26 Product1
2018-02-20 Product1
2018-01-02 Product2
2018-01-07 Product2
2018-01-09 Product2
2018-01-17 Product2
2018-01-28 Product2
Code:
CREATE TABLE myTemp(
Date Date,
ProductName varchar(10))
INSERT INTO myTemp values
('2018-01-01', 'Product1')
,('2018-01-05','Product1')
,('2018-01-09','Product1')
,('2018-01-17','Product1')
,('2018-01-24','Product1')
,('2018-01-26','Product1')
,('2018-02-20','Product1')
,('2018-01-02','Product2')
,('2018-01-07','Product2')
,('2018-01-09','Product2')
,('2018-01-17','Product2')
,('2018-01-28','Product2')
The table can have any number of date's entries for each product.
I want to display the product name, minimum date and min date + 24 days. And I want to do this for each 25 days' bucket.
For example,
In case of product1, 2018-01-01 is the min date and 2018-01-25 is the PLUS 25 date.
BUT, product1 also has records for date greater than 2018-01-25. So I should see one more record for product1 in the output like below:
2018-01-26 2018-02-19 product1
2018-01-26 being the Min Date after 2018-01-25. 2109-02-19 being the PLUS 25 date. and product1 is the product name.
That way, my final output should be:
2018-01-01 2018-01-25 Product1
2018-01-26 2018-02-19 Product1
2018-01-02 2018-01-26 Product2
2018-01-28 2018-02-21 Product2
I tried doing it with min() and DateAdd() but it gives me one row for each product.
DROP TABLE IF EXISTS #MyTemp
select MIN(Date) CurrDate, DateAdd(d, 24, MIN(Date)) CurrPlus25Date, ProductName
into #MyTemp
from myTemp
group by ProductName
select * from #MyTemp
Appreciate any help.
Here is one way using recursive cte. If you have a number / tally table, you can simply take the product cte and cross join with the tally table
; with
product as
(
select ProductName,
minDate = min(Date),
maxDate = max(Date)
from myTemp
group by ProductName
),
productdates as
(
select ProductName, minDate, maxDate,
frDate = minDate, toDate = dateadd(day, 24, minDate)
from product
union all
select ProductName, minDate, maxDate,
frDate = dateadd(day, 1, toDate),
toDate = dateadd(day, 25, toDate)
from productdates
where frDate < maxDate
)
select ProductName, frDate, toDate
from productdates
order by ProductName, frDate
This following query will provide your desired output-
SELECT C.min_datre,C.Plus_24_date,C.ProductName
FROM
(
--Select data for the initial Date Range
SELECT MIN(Date) AS min_datre,DATEADD(DD,24,MIN(Date)) AS Plus_24_date,
ProductName
FROM myTemp
GROUP BY ProductName
UNION ALL
--Select Data for Out of first defined range
SELECT MIN(B.Date),
DATEADD(DD,24,MIN(B.Date)),
ProductName
FROM
(
--Select records per product with date greater
--than overall MIN(Date)+24
SELECT
mt.date Date,
mt.ProductName,
A.min_date
FROM myTemp mt
INNER JOIN (
SELECT MIN(Date) min_date,
DATEADD(DD,24,MIN(Date)) with_24_day,
ProductName
FROM myTemp
GROUP BY ProductName
) A
ON mt.ProductName = A.ProductName
AND mt.Date > A.with_24_day
) B
GROUP BY B.ProductName
) C
ORDER BY 3,1

SQL Running Total Reset on Condition

I have the following table:
Transaction History Table
TransactionHistoryId ProductCode Type Quantity PurchasePrice CurrentPrice
1 Product1 B 10 3.00 2.00
2 Product1 B 5 7.00 2.00
3 Product1 S -7 7.00 2.00
4 Product1 S -8 3.00 3.00
5 Product1 B 4 10.00 10.00
6 Product1 B 5 12.00 12.00
8 Product2 B 8 20.00 20.00
I would like to acheive the following table:
TransactionHistoryId ProductCode Type Quantity PurchasePrice QtyRunning PriceRunning
1 Product1 B 10 3.00 10 30.00
2 Product1 B 5 7.00 15 65.00
3 Product1 S -7 7.00 8 65.00
4 Product1 S -8 3.00 0 0.00
5 Product1 B 4 10.00 4 40.00
6 Product1 B 5 12.00 9 100.00
8 Product2 B 8 20.00 8 160.00
Create Table SQL
IF OBJECT_ID('TEMPDB..#TransactionHistory') IS NOT NULL
DROP TABLE #TransactionHistory
create table #TransactionHistory
(TransactionHistoryId int,
ProductCode varchar(10),
Type char(1),
Quantity smallint,
PurchasePrice decimal(18,2),
CurrentPrice decimal(18,2)
)
insert into #TransactionHistory
values
(1,'Product1','B',10,3.00,2.00),
(2,'Product1','B',5,7.00,2.00),
(3,'Product1','S',-7,7.00,2.00),
(4,'Product1','S',-8,3.00,3.00),
(5,'Product1','B',4,10.00,10.00),
(6,'Product1','B',5,12.00,12.00),
(8,'Product2','B',8,20.00,20.00)
Rules
PriceRunningTotal resets when the quantity running total is 0
PriceRunningTotal sums up only Type = 'B' (buys), when Type = 'S' (sold) keep the previous purchase price running total
Notice there is a Product 2 so it should have it's own running count independent of Product 1
Purpose
A query to ultimately find out the following:
Product Quantity AdjustedPurchasePrice
Product1 9 $11.11
Product2 8 $20
I used the following SQL Server 2012 query to get the result, but I feel it could be done much better:
Query
SELECT *,
PriceRunningTotalFinal =
SUM(CASE
WHEN QuantityRunningTotal = 0 THEN -1 * PriceRunningTotal
WHEN Quantity < 0 THEN 0 ELSE PurchasePrice * Quantity END) OVER
(
PARTITION BY ProductCode
ORDER BY TransactionHistoryId ROWS UNBOUNDED PRECEDING
)
FROM (
SELECT TransactionHistoryId, ProductCode, Type, Quantity, PurchasePrice,
QuantityRunningTotal = SUM(Quantity) OVER
(
PARTITION BY ProductCode
ORDER BY TransactionHistoryId ROWS UNBOUNDED PRECEDING
),
PriceRunningTotal = SUM(CASE WHEN Quantity < 0 THEN 0 ELSE PurchasePrice * Quantity END) OVER
(
PARTITION BY ProductCode
ORDER BY TransactionHistoryId ROWS UNBOUNDED PRECEDING
)
FROM TransactionHistory
) AS Results1
ORDER BY ProductCode;
Problem
Ideally I would of liked to use the QuantityRunningTotal within another query but I can't nest windowed functions.
Anyone know of a more efficient way to achieve this result?
Hmmm. I think something like this:
select th.*,
sum(case when type = 'B' then Quantity * PurchasePrice
else 0
end) over (partition by grp, ProductCode order by TransactionHistoryId
) as PriceRunningTotal
from (select th.*,
sum(case when running_quantity = 0 then 1 else 0 end) over (partition by ProductCode order by TransactionHistoryId) as grp
from (select th.*,
sum(quantity) over (partition by ProductCode order by TransactionHistoryId
) as running_quantity
from TransactionHistory th
) th;
I'm not sure if this is the same logic as your query. For this query:
The innermost subquery calculates the running quantity.
The middle subquery calculates a group based on the number of times the running quantity has been 0.
The outermost query then calculates the running price.

An attempt to create a balance between debit and credit

Well, I'll go directly to the case that is presented to me when trying to make a book with Extract and MUST HAVE in continuous BALANCE.
I was really hanging in my consultation, and I can not find any solution for desired.
Thanked would in some small contribution to some of you.
I'm looking for something like this:
ACCDATE ACCOUNT DEBIT CREDIT BALANCE
2013-01-01 00:00:00 11200 0.00 1500.00 -1500.00
2013-01-01 00:00:00 11200 0.00 60.00 -1560.00
2013-01-01 00:00:00 11200 0.00 400.00 -1960.00
2013-01-01 00:00:00 11200 0.00 100.00 -2060.00
2013-01-01 00:00:00 11200 0.00 300.00 -2360.00
2013-01-01 00:00:00 11200 0.00 250.00 -2910.00
OR:
ACCDATE ACCOUNT DEBIT CREDIT BALANCE
2013-01-01 00:00:00 11200 1500.00 0 1500.00
2013-01-01 00:00:00 11200 0.00 60.00 1440.00
2013-01-01 00:00:00 11200 0.00 400.00 1040.00
2013-01-01 00:00:00 11200 0.00 40 1000.00
2013-01-01 00:00:00 11200 300 0 1300.00
2013-01-01 00:00:00 11200 0.00 250.00 1550.00
I really do not require account type filter it by this time, but specific.
The idea is that with my Query still does not give me that result.
They can buy creating a provisional or temporary table with the same shown below:
INSERT INTO Accounting (AccDate,DebitCredit,Account,Amount) VALUES ('20110101','D',11200,1500)
INSERT INTO Accounting (AccDate,DebitCredit,Account,Amount) VALUES ('20110101','C',11200,60)
INSERT INTO Accounting (AccDate,DebitCredit,Account,Amount) VALUES ('20110102','D',11200,400)
INSERT INTO Accounting (AccDate,DebitCredit,Account,Amount) VALUES ('20110102','C',11200,100)
INSERT INTO Accounting (AccDate,DebitCredit,Account,Amount) VALUES ('20110102','C',11200,300)
INSERT INTO Accounting (AccDate,DebitCredit,Account,Amount) VALUES ('20110102','C',11200,250)
WITH CTE_FIRST AS
(
SELECT ACCDATE,
ACCOUNT,
CASE WHEN DEBITCREDIT='D' THEN AMOUNT ELSE 0 END AS DEBIT,
CASE WHEN DEBITCREDIT='C' THEN AMOUNT ELSE 0 END AS CREDIT,
ROW_NUMBER()OVER(ORDER BY ACCOUNT,ACCDATE) RN
FROM ACCOUNTING
WHERE ACCDATE >='20130101'
)
,CTE_SECOND AS(
SELECT *,
ISNULL((SELECT TOP 1 DEBIT FROM CTE_FIRST B WHERE B.ACCOUNT=A.ACCOUNT AND B.RN<A.RN ORDER BY RN DESC),0) COL1,
ISNULL((SELECT TOP 1 CREDIT FROM CTE_FIRST B WHERE B.ACCOUNT=A.ACCOUNT AND B.RN<A.RN ORDER BY RN DESC),0) COL2
FROM CTE_FIRST A
)
SELECT ACCDATE,ACCOUNT,DEBIT,CREDIT,
CASE WHEN DEBIT=0 THEN 0-(CREDIT+COL2) ELSE DEBIT+COL1 END BALANCE
FROM CTE_SECOND
Something happens in the validation of sum or not it's taking so linear consulting ....
All of this inquiry, I tried to help me with material that I got on the web. But it gives me the total response.
In the end I got this solution, but it becomes very slow the process.
Is there a way to optimize it?
Very slow for real, and it does not work for high queries.
DECLARE #T TABLE( FECHA DATETIME, COMENTARIO NVARCHAR (300), CUENTA
VARCHAR(15), DEBE NUMERIC(15,2), HABER NUMERIC(15,2) )
INSERT INTO #T SELECT FECHA, COMENTARIO, CUENTA, DEBE, HABER FROM
DIARIOAPUNTES;
/* INSERT INTO #T VALUES ('001-0001','20130102',100,0); INSERT INTO #T
VALUES ('001-0001','20130102',0,200); INSERT INTO #T VALUES
('001-0001','20130102',100,0); INSERT INTO #T VALUES
('001-0001','20130103',100,0); INSERT INTO #T VALUES
('001-0001','20130105',0,100); INSERT INTO #T VALUES
('001-0002','20130105',100,0); INSERT INTO #T VALUES
('001-0002','20130106',500,0);
*/
--DEBIT - CREDIT + BALANCE
WITH T_ROW AS (
SELECT (ROW_NUMBER() OVER(ORDER BY (T1_1.FECHA) ASC)) AS CONTADOR, FECHA, T1_1.CUENTA, T1_1.COMENTARIO, T1_1.DEBE, T1_1.HABER
FROM #T T1_1 )
SELECT T1.CONTADOR, T1.CUENTA, T1.COMENTARIO AS DESCRIPCION,
Convert(CHAR(10), T1.FECHA, 103) AS FECHA, T1.DEBE, T1.HABER,
ROUND(T1.DEBE-T1.HABER + COALESCE(T2.SALDO,0),2) AS SALDO FROM T_ROW
T1
CROSS APPLY(
SELECT ROUND(SUM(DEBE)-SUM(HABER),2) AS SALDO
FROM T_ROW T2
WHERE T2.CONTADOR < T1.CONTADOR AND T1.CUENTA = T2.CUENTA
) AS T2
--WHERE T1.FECHA BETWEEN '20130101' AND '20131231'
ORDER BY T1.CUENTA, T1.FECHA
--WHERE T1.ACCOUNTNO = '001-0001'

Running Total on date column

I have the following data in my table:
id invoice_id date ammount
1 1 2012-01-01 100.00
20 1 2012-01-31 50.00
470 1 2012-01-15 300.00
Now, I need to calculate running total for an invoice in some period. So, the output for this data sample should look like this:
id invoice_id date ammount running_total
1 1 2012-01-01 100.00 100.00
470 1 2012-01-15 300.00 400.00
20 1 2012-01-31 50.00 450.00
I tried with this samples http://www.sqlusa.com/bestpractices/runningtotal/ and several others, but the problem is that I could have entries like id 20, date 2012-01-31 and id 120, date 2012-01-01, and then I couldn't use NO = ROW_NUMBER(over by date)... in first select and then ID < NO in second select for calculating running total.
DECLARE #DateStart DATE='2012-01-01';
WITH cte
AS (SELECT id = Row_number() OVER(ORDER BY [date]),
DATE,
myid = id,
invoice_id,
orderdate = CONVERT(DATE, DATE),
ammount
FROM [Table_2]
WHERE DATE >= #DateStart)
SELECT myid,
invoice_id,
DATE,
ammount,
runningtotal = (SELECT SUM(ammount)
FROM cte
WHERE id <= a.id)
FROM cte AS a
ORDER BY id