How to add status to the table - sql

I have the following table where is clipping from my db. I have 2 types of contracts.
I: client pays for first 6mth 60$, next 6mth 120$ (111 client)
II: client pays for first 6mth 60$ but if want still pays 60$ the contract will be extended at 6mth, whole contract is 18mth. (321 client who still pays)
ID_Client | Amount | Amount_charge | Lenght | Date_from | Date_to | Reverse
--------------------------------------------------------------------------------
111 60 60 12 2015-01-01 2015-01-31 12
111 60 60 12 2015-02-01 2015-02-28 11
111 60 60 12 2015-03-01 2015-03-31 10
111 60 60 12 2015-04-01 2015-04-30 9
111 60 60 12 2015-05-01 2015-05-31 8
111 60 60 12 2015-06-01 2015-06-30 7
111 120 60 12 2015-07-01 2015-07-31 6
111 120 60 12 2015-08-01 2015-08-31 5
111 120 60 12 2015-09-01 2015-09-30 4
111 120 60 12 2015-10-01 2015-10-31 3
111 120 60 12 2015-11-01 2015-11-30 2
111 120 60 12 2015-12-01 2015-12-31 1
111 120 60 12 2016-01-01 2015-01-31 0
111 120 60 12 2016-02-01 2015-02-29 0
321 60 60 12 2015-01-01 2015-01-31 12
321 60 60 12 2015-02-01 2015-02-28 11
321 60 60 12 2015-03-01 2015-03-31 10
321 60 60 12 2015-04-01 2015-04-30 9
321 60 60 12 2015-05-01 2015-05-31 8
321 60 60 12 2015-06-01 2015-06-30 7
321 60 60 12 2015-07-01 2015-07-31 6
321 60 60 12 2015-08-01 2015-08-31 5
321 60 60 12 2015-09-01 2015-09-30 4
321 60 60 12 2015-10-01 2015-10-31 3
321 60 60 12 2015-11-01 2015-11-30 2
321 60 60 12 2015-12-01 2015-12-31 1
321 60 60 12 2016-01-01 2016-01-30 0
321 60 60 12 2016-02-01 2016-02-31 0
321 60 60 12 2016-03-01 2016-03-30 0
321 60 60 12 2016-04-01 2016-04-31 0
I need to add status column.
A - normal period of agreement
D - where the agreement is doubled after 6mth but after 12mth is E(nd of agreemnt)
E - where contract is finished
L - where contract after 6mth was extended, after 18mth the status will be type E
For 321 Client after 12mth the lenght of contract was updated from 12 to 18
I have a lot of clients so i think better will be using loop to go by all clients?
ID_Client | Amount | Amount_charge | Lenght | Date_from | Date_to | Reverse | Status
-----------------------------------------------------------------------------------------
111 60 60 12 2015-01-01 2015-01-31 12 A
111 60 60 12 2015-02-01 2015-02-28 11 A
111 60 60 12 2015-03-01 2015-03-31 10 A
111 60 60 12 2015-04-01 2015-04-30 9 A
111 60 60 12 2015-05-01 2015-05-31 8 A
111 60 60 12 2015-06-01 2015-06-30 7 A
111 120 60 12 2015-07-01 2015-07-31 6 D
111 120 60 12 2015-08-01 2015-08-31 5 D
111 120 60 12 2015-09-01 2015-09-30 4 D
111 120 60 12 2015-10-01 2015-10-31 3 D
111 120 60 12 2015-11-01 2015-11-30 2 D
111 120 60 12 2015-12-01 2015-12-31 1 D
111 120 60 12 2016-01-01 2015-01-31 0 E
111 120 60 12 2016-02-01 2015-02-29 0 E
321 60 60 12 2015-01-01 2015-01-31 12 A
321 60 60 12 2015-02-01 2015-02-28 11 A
321 60 60 12 2015-03-01 2015-03-31 10 A
321 60 60 12 2015-04-01 2015-04-30 9 A
321 60 60 12 2015-05-01 2015-05-31 8 A
321 60 60 12 2015-06-01 2015-06-30 7 A
321 60 60 12 2015-07-01 2015-07-31 6 L
321 60 60 12 2015-08-01 2015-08-31 5 L
321 60 60 12 2015-09-01 2015-09-30 4 L
321 60 60 12 2015-10-01 2015-10-31 3 L
321 60 60 12 2015-11-01 2015-11-30 2 L
321 60 60 12 2015-12-01 2015-12-31 1 L
321 60 60 18 2016-01-01 2016-01-30 0 L
321 60 60 18 2016-02-01 2016-02-31 0 L
321 60 60 18 2016-03-01 2016-03-30 0 L
321 60 60 18 2016-04-01 2016-04-31 0 L

If the Reverse column is what I think:
update table1 a
set "Status"=
CASE
WHEN A."Reverse" > 6 THEN
'A'
WHEN A."Reverse" > 0 THEN
DECODE (A."Amount", A."Amount_charge", 'L', 'D')
ELSE
CASE
WHEN A."Amount" <> A."Amount_charge" THEN
'E'
ELSE
CASE WHEN ADD_MONTHS ( (SELECT b."Date_from" FROM table1 b WHERE a."ID_Client" = b."ID_Client" AND b."Reverse" = 1),6) > a."Date_from" THEN 'L'
ELSE
'E'
END
END
END
Better is to calculate the sums. The amount per month come from first payment. Something like this:
DECLARE
CURSOR c2
IS
SELECT ID_CLIENT, --AMOUNT, AMOUNT_CHARGE, LENGTH, DATE_FROM, DATE_TO, REVERSE, STATUS,
FIRST_VALUE (amount_charge) OVER (PARTITION BY id_client ORDER BY date_from) first_amount_charge,
SUM (amount) OVER (PARTITION BY id_client ORDER BY date_from) sum_amount,
SUM (amount_charge) OVER (PARTITION BY id_client ORDER BY date_from) sum_amount_charge
FROM TABLE2
FOR UPDATE NOWAIT;
BEGIN
FOR c1 IN c2
LOOP
UPDATE table2
SET status = CASE WHEN c1.sum_amount <= 6 * c1.first_amount_charge THEN 'A'
WHEN c1.sum_amount > 18 * c1.first_amount_charge THEN 'E'
WHEN c1.sum_amount > c1.sum_amount_charge THEN 'D'
ELSE 'L'
END
WHERE CURRENT OF c2;
END LOOP;
END;

Related

Replacement of values by logical condition by groups in SQL Server

Here's my sample data
shop_code product_id doc_date ship_count mark_1 outputer y
-----------------------------------------------------------------------------
1 00664НСК 11628 2015-01-03 00:00:00.000 12 1 8 1
2 00664НСК 11628 2015-01-05 00:00:00.000 7 1 8 1
3 00664НСК 11628 2015-01-06 00:00:00.000 24 0 8 1
4 00664НСК 11628 2015-01-07 00:00:00.000 18 1 8 1
5 00664НСК 11628 2015-01-08 00:00:00.000 12 1 8 1
6 00664НСК 11628 2015-01-09 00:00:00.000 18 0 8 1
7 00664НСК 11628 2015-01-10 00:00:00.000 6 0 6 1
8 00664НСК 11628 2015-01-11 00:00:00.000 6 1 6 1
9 00664НСК 11628 2015-01-12 00:00:00.000 6 1 6 1
10 00664НСК 11628 2015-01-13 00:00:00.000 18 1 12 0
11 00664НСК 11628 2015-01-14 00:00:00.000 6 1 6 0
12 00664НСК 11628 2015-01-15 00:00:00.000 18 1 12 0
13 00664НСК 11628 2015-01-16 00:00:00.000 12 1 12 1
14 00664НСК 11628 2015-01-17 00:00:00.000 18 1 12 1
15 00664НСК 11628 2015-01-18 00:00:00.000 12 1 12 1
16 00664НСК 11628 2015-01-19 00:00:00.000 10 1 10 0
17 00664НСК 11628 2015-01-20 00:00:00.000 24 1 12 0
18 00664НСК 11628 2015-01-21 00:00:00.000 6 1 6 0
19 00664НСК 11628 2015-01-24 00:00:00.000 6 1 6 0
20 00664НСК 11628 2015-01-25 00:00:00.000 6 0 6 0
21 00664НСК 11628 2015-01-26 00:00:00.000 10 0 10 1
22 00664НСК 11628 2015-01-27 00:00:00.000 6 1 6 0
23 00664НСК 11628 2015-01-28 00:00:00.000 10 1 10 0
24 00664НСК 11628 2015-01-29 00:00:00.000 70 0 12 1
25 00664НСК 11628 2015-01-30 00:00:00.000 100 1 12 1
Similar question I have asked for R and got working solution, but now I want do it using T-SQL.
I need observe such a condition: if y = 1 and mark1 = 1, then the output by mark1=1 must be replaced by the first value that goes for y = 0 and mark1 = 1 in the output variable.
If the first value that goes for Y = 0 and mark1 = 1 in the output is more than the ship_count, then in output left the actual value of ship_count
Zero category of mark1 for output, we don't touch.
This operation must be done by group ship_code+product_id
So the desired output should look like this:
shop_code product_id doc_date ship_count mark_1 outputer y
----------------------------------------------------------------------------
1 00664НСК 11628 2015-01-03 00:00:00.000 12 1 *12 1
2 00664НСК 11628 2015-01-05 00:00:00.000 7 1 *7 1
3 00664НСК 11628 2015-01-06 00:00:00.000 24 0 24 1
4 00664НСК 11628 2015-01-07 00:00:00.000 18 1 *12 1
5 00664НСК 11628 2015-01-08 00:00:00.000 12 1 *12 1
6 00664НСК 11628 2015-01-09 00:00:00.000 18 0 18 1
7 00664НСК 11628 2015-01-10 00:00:00.000 6 0 6 1
8 00664НСК 11628 2015-01-11 00:00:00.000 6 1 6 1
9 00664НСК 11628 2015-01-12 00:00:00.000 6 1 6 1
10 00664НСК 11628 2015-01-13 00:00:00.000 18 1 *12 0
11 00664НСК 11628 2015-01-14 00:00:00.000 6 1 6 0
12 00664НСК 11628 2015-01-15 00:00:00.000 18 1 12 0
13 00664НСК 11628 2015-01-16 00:00:00.000 12 1 *10 1
14 00664НСК 11628 2015-01-17 00:00:00.000 18 1 *10 1
15 00664НСК 11628 2015-01-18 00:00:00.000 12 1 *10 1
16 00664НСК 11628 2015-01-19 00:00:00.000 10 1 10 0
17 00664НСК 11628 2015-01-20 00:00:00.000 24 1 12 0
18 00664НСК 11628 2015-01-21 00:00:00.000 6 1 6 0
19 00664НСК 11628 2015-01-24 00:00:00.000 6 1 6 0
20 00664НСК 11628 2015-01-25 00:00:00.000 6 0 6 0
21 00664НСК 11628 2015-01-26 00:00:00.000 10 0 10 1
22 00664НСК 11628 2015-01-27 00:00:00.000 6 1 6 1
23 00664НСК 11628 2015-01-28 00:00:00.000 20 1 *12 0
24 00664НСК 11628 2015-01-29 00:00:00.000 70 1 12 0
25 00664НСК 11628 2015-01-30 00:00:00.000 100 1 12 1
Good evening,
You should use a case statement to do your job.
For finding the first value for the describing clauses , use a subquery in which you keep the order that you wish(order by) and select the top 1 value.
Give a try and if you face some issues ask again.

LAG / OVER / PARTITION / ORDER BY using conditions - SQL Server 2017

I have a table that looks like this:
Date AccountID Amount
2018-01-01 123 12
2018-01-06 123 150
2018-02-14 123 11
2018-05-06 123 16
2018-05-16 123 200
2018-06-01 123 18
2018-06-15 123 17
2018-06-18 123 110
2018-06-30 123 23
2018-07-01 123 45
2018-07-12 123 116
2018-07-18 123 60
This table has multiple dates and IDs, along with multiple Amounts. For each individual row, I want grab the last Date where Amount was over a specific value for that specific AccountID. I have been trying to use the LAG( Date, 1 ) in combination with several variatons of CASE and OVER ( PARTITION BY AccountID ORDER BY Date ) statements but I've had no luck. Ultimately, this is what I would like my SELECT statement to return.
Date AccountID Amount LastOverHundred
2018-01-01 123 12 NULL
2018-01-06 123 150 2018-01-06
2018-02-14 123 11 2018-01-06
2018-05-06 123 16 2018-01-06
2018-05-16 123 200 2018-05-16
2018-06-01 123 18 2018-05-16
2018-06-15 123 17 2018-05-16
2018-06-18 123 110 2018-06-18
2018-06-30 123 23 2018-06-18
2018-07-01 123 45 2018-06-18
2018-07-12 123 116 2018-07-12
2018-07-18 123 60 2018-07-12
Any help with this would be greatly appreciated.
Use a cumulative conditional max():
select t.*,
max(case when amount > 100 then date end) over (partition by accountid order by date) as lastoverhundred
from t;

grouping a table with different dates

I have a table like below,
SalesId ItemId DateSale USDVal
ABC 01A 2018-04-01 52
ABC 01B 2018-04-01 300
ABC 01C 2018-04-01 12
ABC 01D 2018-04-01 62
ABC 01A 2018-03-23 66
MNB 01A 2018-01-01 584
MNB 01A 2018-02-20 320
MNB 01F 2018-02-20 5
I want to write a query that selects the last date for each SalesId and shows those records so the result would look something like below.
Result
SalesId ItemId DateSale USDVal
ABC 01A 2018-04-01 52
ABC 01B 2018-04-01 300
ABC 01C 2018-04-01 12
ABC 01D 2018-04-01 62
MNB 01A 2018-02-20 320
MNB 01F 2018-02-20 5
In SQL Server, the fastest way is often a correlated subquery:
select t.*
from t
where t.datesale = (select max(t2.datesale) from t t2 where t2.salesid = t.salesid);

Dates between two dates from a table

I can't find the specific answer to this question but apologies if it has been asked previously.
I have the following example table which I have kept simple but it contains more rows and Types. It gets updated frequently.
Type From To Qty
1 2016-01-01 00:00:00.0000000 2016-01-03 00:00:00.0000000 30
1 2016-01-04 00:00:00.0000000 2016-01-05 00:00:00.0000000 31
1 2016-01-06 00:00:00.0000000 NULL 31
2 2016-04-24 00:00:00.0000000 NULL 15
I want to be able to update a table every day (as shown below) so it shows all of the dates between (and including) the From and To dates. The Qty for the relevant date must be displayed up to todays date where the TO is NULL.
Type Date Qty
1 2016-01-01 00:00:00.0000000 30
1 2016-01-02 00:00:00.0000000 30
1 2016-01-03 00:00:00.0000000 30
1 2016-04-04 00:00:00.0000000 31
1 2016-04-05 00:00:00.0000000 31
1 2016-04-06 00:00:00.0000000 31
1 2016-04-07 00:00:00.0000000 31
1 .... up to today where TO is NULL
1 2016-07-25 00:00:00.0000000 31
2 2016-04-24 00:00:00.0000000 15
2 .... up to today where TO is NULL
2 2016-07-25 00:00:00.0000000 15
Thank you in advance for your help.
Using Numbers table..
Demo Here
select b.*,qty from #test
cross apply
(
select dateadd(day,n,fromdate) from
numbers
where n<=
case when todate is null
then datediff(day,fromdate,getdate()) else datediff(day,fromdate,todate) end
) b(upd)
You can do this using a recursive CTE to generate all of the dates and JOIN to that for the result:
Test Data
Create Table Test
(
[Type] Int,
[From] Date,
[To] Date,
Qty Int
)
Insert Test
Values
(1, '2016-01-01', '2016-01-03', 30 ),
(1, '2016-01-04', '2016-01-05', 31 ),
(1, '2016-01-06', NULL, 31 ),
(2, '2016-04-24', NULL, 15 )
Query
;With MinMax As
(
Select Min([From]) MinFrom,
Max([To]) MaxTo,
Convert(Date, GetDate()) Today
From Test
), Date (Date) As
(
Select MinFrom
From MinMax
Union All
Select DateAdd(Day, 1, Date)
From Date
Where Date < (Select MaxTo From MinMax)
Or Date < (Select Today From MinMax)
)
Select T.[Type],
D.[Date],
T.Qty
From Test T
Join Date D On D.Date Between T.[From] And Coalesce(T.[To], Convert(Date, GetDate()))
Order By T.[Type], D.[Date]
Option (MaxRecursion 0)
Results
Type Date Qty
1 2016-01-01 30
1 2016-01-02 30
1 2016-01-03 30
1 2016-01-04 31
1 2016-01-05 31
1 2016-01-06 31
1 2016-01-07 31
1 2016-01-08 31
1 2016-01-09 31
1 2016-01-10 31
1 2016-01-11 31
1 2016-01-12 31
1 2016-01-13 31
1 2016-01-14 31
1 2016-01-15 31
1 2016-01-16 31
1 2016-01-17 31
1 2016-01-18 31
1 2016-01-19 31
1 2016-01-20 31
1 2016-01-21 31
1 2016-01-22 31
1 2016-01-23 31
1 2016-01-24 31
1 2016-01-25 31
1 2016-01-26 31
1 2016-01-27 31
1 2016-01-28 31
1 2016-01-29 31
1 2016-01-30 31
1 2016-01-31 31
1 2016-02-01 31
1 2016-02-02 31
1 2016-02-03 31
1 2016-02-04 31
1 2016-02-05 31
1 2016-02-06 31
1 2016-02-07 31
1 2016-02-08 31
1 2016-02-09 31
1 2016-02-10 31
1 2016-02-11 31
1 2016-02-12 31
1 2016-02-13 31
1 2016-02-14 31
1 2016-02-15 31
1 2016-02-16 31
1 2016-02-17 31
1 2016-02-18 31
1 2016-02-19 31
1 2016-02-20 31
1 2016-02-21 31
1 2016-02-22 31
1 2016-02-23 31
1 2016-02-24 31
1 2016-02-25 31
1 2016-02-26 31
1 2016-02-27 31
1 2016-02-28 31
1 2016-02-29 31
1 2016-03-01 31
1 2016-03-02 31
1 2016-03-03 31
1 2016-03-04 31
1 2016-03-05 31
1 2016-03-06 31
1 2016-03-07 31
1 2016-03-08 31
1 2016-03-09 31
1 2016-03-10 31
1 2016-03-11 31
1 2016-03-12 31
1 2016-03-13 31
1 2016-03-14 31
1 2016-03-15 31
1 2016-03-16 31
1 2016-03-17 31
1 2016-03-18 31
1 2016-03-19 31
1 2016-03-20 31
1 2016-03-21 31
1 2016-03-22 31
1 2016-03-23 31
1 2016-03-24 31
1 2016-03-25 31
1 2016-03-26 31
1 2016-03-27 31
1 2016-03-28 31
1 2016-03-29 31
1 2016-03-30 31
1 2016-03-31 31
1 2016-04-01 31
1 2016-04-02 31
1 2016-04-03 31
1 2016-04-04 31
1 2016-04-05 31
1 2016-04-06 31
1 2016-04-07 31
1 2016-04-08 31
1 2016-04-09 31
1 2016-04-10 31
1 2016-04-11 31
1 2016-04-12 31
1 2016-04-13 31
1 2016-04-14 31
1 2016-04-15 31
1 2016-04-16 31
1 2016-04-17 31
1 2016-04-18 31
1 2016-04-19 31
1 2016-04-20 31
1 2016-04-21 31
1 2016-04-22 31
1 2016-04-23 31
1 2016-04-24 31
1 2016-04-25 31
1 2016-04-26 31
1 2016-04-27 31
1 2016-04-28 31
1 2016-04-29 31
1 2016-04-30 31
1 2016-05-01 31
1 2016-05-02 31
1 2016-05-03 31
1 2016-05-04 31
1 2016-05-05 31
1 2016-05-06 31
1 2016-05-07 31
1 2016-05-08 31
1 2016-05-09 31
1 2016-05-10 31
1 2016-05-11 31
1 2016-05-12 31
1 2016-05-13 31
1 2016-05-14 31
1 2016-05-15 31
1 2016-05-16 31
1 2016-05-17 31
1 2016-05-18 31
1 2016-05-19 31
1 2016-05-20 31
1 2016-05-21 31
1 2016-05-22 31
1 2016-05-23 31
1 2016-05-24 31
1 2016-05-25 31
1 2016-05-26 31
1 2016-05-27 31
1 2016-05-28 31
1 2016-05-29 31
1 2016-05-30 31
1 2016-05-31 31
1 2016-06-01 31
1 2016-06-02 31
1 2016-06-03 31
1 2016-06-04 31
1 2016-06-05 31
1 2016-06-06 31
1 2016-06-07 31
1 2016-06-08 31
1 2016-06-09 31
1 2016-06-10 31
1 2016-06-11 31
1 2016-06-12 31
1 2016-06-13 31
1 2016-06-14 31
1 2016-06-15 31
1 2016-06-16 31
1 2016-06-17 31
1 2016-06-18 31
1 2016-06-19 31
1 2016-06-20 31
1 2016-06-21 31
1 2016-06-22 31
1 2016-06-23 31
1 2016-06-24 31
1 2016-06-25 31
1 2016-06-26 31
1 2016-06-27 31
1 2016-06-28 31
1 2016-06-29 31
1 2016-06-30 31
1 2016-07-01 31
1 2016-07-02 31
1 2016-07-03 31
1 2016-07-04 31
1 2016-07-05 31
1 2016-07-06 31
1 2016-07-07 31
1 2016-07-08 31
1 2016-07-09 31
1 2016-07-10 31
1 2016-07-11 31
1 2016-07-12 31
1 2016-07-13 31
1 2016-07-14 31
1 2016-07-15 31
1 2016-07-16 31
1 2016-07-17 31
1 2016-07-18 31
1 2016-07-19 31
1 2016-07-20 31
1 2016-07-21 31
1 2016-07-22 31
1 2016-07-23 31
1 2016-07-24 31
1 2016-07-25 31
1 2016-07-26 31
2 2016-04-24 15
2 2016-04-25 15
2 2016-04-26 15
2 2016-04-27 15
2 2016-04-28 15
2 2016-04-29 15
2 2016-04-30 15
2 2016-05-01 15
2 2016-05-02 15
2 2016-05-03 15
2 2016-05-04 15
2 2016-05-05 15
2 2016-05-06 15
2 2016-05-07 15
2 2016-05-08 15
2 2016-05-09 15
2 2016-05-10 15
2 2016-05-11 15
2 2016-05-12 15
2 2016-05-13 15
2 2016-05-14 15
2 2016-05-15 15
2 2016-05-16 15
2 2016-05-17 15
2 2016-05-18 15
2 2016-05-19 15
2 2016-05-20 15
2 2016-05-21 15
2 2016-05-22 15
2 2016-05-23 15
2 2016-05-24 15
2 2016-05-25 15
2 2016-05-26 15
2 2016-05-27 15
2 2016-05-28 15
2 2016-05-29 15
2 2016-05-30 15
2 2016-05-31 15
2 2016-06-01 15
2 2016-06-02 15
2 2016-06-03 15
2 2016-06-04 15
2 2016-06-05 15
2 2016-06-06 15
2 2016-06-07 15
2 2016-06-08 15
2 2016-06-09 15
2 2016-06-10 15
2 2016-06-11 15
2 2016-06-12 15
2 2016-06-13 15
2 2016-06-14 15
2 2016-06-15 15
2 2016-06-16 15
2 2016-06-17 15
2 2016-06-18 15
2 2016-06-19 15
2 2016-06-20 15
2 2016-06-21 15
2 2016-06-22 15
2 2016-06-23 15
2 2016-06-24 15
2 2016-06-25 15
2 2016-06-26 15
2 2016-06-27 15
2 2016-06-28 15
2 2016-06-29 15
2 2016-06-30 15
2 2016-07-01 15
2 2016-07-02 15
2 2016-07-03 15
2 2016-07-04 15
2 2016-07-05 15
2 2016-07-06 15
2 2016-07-07 15
2 2016-07-08 15
2 2016-07-09 15
2 2016-07-10 15
2 2016-07-11 15
2 2016-07-12 15
2 2016-07-13 15
2 2016-07-14 15
2 2016-07-15 15
2 2016-07-16 15
2 2016-07-17 15
2 2016-07-18 15
2 2016-07-19 15
2 2016-07-20 15
2 2016-07-21 15
2 2016-07-22 15
2 2016-07-23 15
2 2016-07-24 15
2 2016-07-25 15
2 2016-07-26 15

inserting result of a function into a table

I get consequent 24 months from the following table valued function. I need to insert these months in another table where the result should be like this:
Week Period
1 2010-02-01
2 2010-02-01
3 2010-02-01
4 2010-02-01
5 2010-03-01
6 2010-03-01
7 2010-03-01
8 2010-03-01
9 2010-03-01
10 2010-04-01
11 2010-04-01
12 2010-04-01
13 2010-04-01
14 2010-05-01
15 2010-05-01
16 2010-05-01
17 2010-05-01
18 2010-06-01
19 2010-06-01
20 2010-06-01
21 2010-06-01
22 2010-06-01
23 2010-07-01
24 2010-07-01
25 2010-07-01
26 2010-07-01
27 2010-08-01
28 2010-08-01
29 2010-08-01
30 2010-08-01
31 2010-09-01
32 2010-09-01
33 2010-09-01
34 2010-09-01
35 2010-09-01
36 2010-10-01
37 2010-10-01
38 2010-10-01
39 2010-10-01
40 2010-11-01
41 2010-11-01
42 2010-11-01
43 2010-11-01
44 2010-12-01
45 2010-12-01
46 2010-12-01
47 2010-12-01
48 2010-12-01
49 2011-01-01
50 2011-01-01
51 2011-01-01
52 2011-01-01
53 2011-02-01
54 2011-02-01
55 2011-02-01
56 2011-02-01
57 2011-03-01
58 2011-03-01
59 2011-03-01
60 2011-03-01
61 2011-03-01
62 2011-04-01
63 2011-04-01
64 2011-04-01
65 2011-04-01
66 2011-05-01
67 2011-05-01
68 2011-05-01
69 2011-05-01
70 2011-06-01
71 2011-06-01
72 2011-06-01
73 2011-06-01
74 2011-06-01
75 2011-07-01
76 2011-07-01
77 2011-07-01
78 2011-07-01
79 2011-08-01
80 2011-08-01
81 2011-08-01
82 2011-08-01
83 2011-09-01
84 2011-09-01
85 2011-09-01
86 2011-09-01
87 2011-09-01
88 2011-10-01
89 2011-10-01
90 2011-10-01
91 2011-10-01
92 2011-11-01
93 2011-11-01
94 2011-11-01
95 2011-11-01
96 2011-12-01
97 2011-12-01
98 2011-12-01
99 2011-12-01
100 2011-12-01
101 2012-01-01
102 2012-01-01
103 2012-01-01
104 2012-01-01
My function is as follows:
ALTER FUNCTION [dbo].[sun_care1](#start_period date, #end_period date)
RETURNS #date TABLE (
Period date NOT NULL
)
AS
BEGIN
--& DATEADD (MONTH,1,#start_period)
WHILE (#end_period <= #start_period) BEGIN
SET #end_period= DATEADD(MONTH,1,#end_period)
--set #start_period =CAST(#start_period as varchar(max))
INSERT INTO #date VALUES (#end_period)
END;
RETURN;
END;
In SQLServer2005+ use CTE and master..spt_values system table. Also you can use Sequence tables instead of master..spt_values system table.
Modified function
ALTER FUNCTION [dbo].[sun_care1](#start_period date, #end_period date)
RETURNS #date TABLE (Period date NOT NULL)
AS
BEGIN
--& DATEADD (MONTH,1,#start_period)
WHILE (#start_period <= #end_period)
BEGIN
SET #start_period= DATEADD(MONTH, 1, #start_period)
--set #start_period =CAST(#start_period as varchar(max))
INSERT INTO #date
VALUES(#start_period)
END;
RETURN;
END;
INSERT statement with using CTE and master..spt_values system table
DECLARE #start_period date = '20100101',
#end_period date = '20111201'
;WITH cte AS
(
SELECT -1 AS rn
UNION ALL
SELECT rn + 3
FROM cte
WHERE rn < DATEDIFF(MONTH, #start_period, #end_period) * 3
), cte2 AS
(
SELECT *, ROW_NUMBER() OVER (ORDER BY Period) AS rn
FROM [dbo].[sun_care1](#start_period, #end_period)
)
INSERT AnotherTableName(columnName)
SELECT Period
FROM cte2 s LEFT JOIN cte c ON s.rn = c.rn
CROSS APPLY (
SELECT number
FROM master..spt_values v
WHERE v.type = 'P'
AND v.number < CASE WHEN c.rn IS NULL
THEN 4 ELSE 5 END
) o