Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2005 Forums
 Transact-SQL (2005)
 help with this function -add value -evry first day

Author  Topic 

ilan
Starting Member

21 Posts

Posted - 2007-12-08 : 13:53:05
need help with this function !
first prolem
this line
--------------------------------------------------------
(convert(int,(datediff(dd,b.unit_date,d.dt) / 30)) % 4) + 1)
-------------------------------------------------------------
i don't get in unit value the correct division the "/30"
how to handling in month 28 days, 29 days, 30 days ,31 days ???
i only need to change the unit value evry first day of the month !!!

like checking the value of the previous Month and change it from "1" to "2" and next month "3" ....... 4 >> 1 >> 2...
the employee move location evry first of the month

second problem
how to add value date for field "unit"
i need to separate the common date in the field "unit" and field "empid"
need to add another field date for the unit
so i can fill the table like this

insert empbase (empid,basedate,unit_date) values (12345,'2007/1/1','2007/3/1')

like this i can
1) set date for "basedate" start DATE
2)set date for "unit_date" start DATE(once a month in the first day=1)

so how to fix this function and to add date for "unit_date" reference
like this i can add to the employee a shift forom date ="basedate"
and a UNIT from "unit_date" (once a month in the first day=1)
the "unit_date" is the start date for add to the employee the UNIT value (1-4)

TNX


-- need a list of employee ids with a basedate set to when they start with shift_code=1, unit=1
-- this is a minimal tale to show the format
-- extra columns could be added with other info (e.g. name)
create table empbase (
empid int,
basedate datetime
)

-- fill with test data
insert empbase (empid,basedate) values (12345,'2007/1/1')
insert empbase (empid,basedate) values (88877,'2007/1/5')
insert empbase (empid,basedate) values (98765,'2007/1/20')
insert empbase (empid,basedate) values (99994,'2007/6/5')
go
-------------------------------
create function shifts (
@mth tinyint,
@yr smallint
)
returns
@table_var
table (
empid int,
date datetime,
shift_code int,
unit int)
as
-- generate daily shift pattern 1,1,2,2,3,3,4,5,... changing units 1,2,3,4,... every 30 days.
begin
declare @d1 datetime
declare @d31 datetime
set @d1=convert(datetime,convert(char(8),@yr*10000+@mth*100+1))
set @d31=dateadd(dd,-1,dateadd(mm,1,@d1))

;with n01 (i) as (select 0 as 'i' union all select 1)
,seq (n) as (
select
d1.i+(2*d2.i)+(4*d3.i)+(8*d4.i)+(16*d5.i) as 'n'
from
n01 as d1
cross join
n01 as d2
cross join
n01 as d3
cross join
n01 as d4
cross join
n01 as d5)
,dates (dt) as (
select
dateadd(dd,n,@d1) as 'dt'
from
seq
where
dateadd(dd,n,@d1) <= @d31)
,modval (mod,val) as (
select 0,1 union all
select 1,1 union all
select 2,2 union all
select 3,2 union all
select 4,3 union all
select 5,3 union all
select 6,4 union all
select 7,5)
insert @table_var
select
b.empid,
d.dt,
(select val from modval where mod=(datediff(dd,b.basedate,d.dt) % 8)),
((convert(int,(datediff(dd,b.basedate,d.dt) / 30)) % 4) + 1)
from
empbase b, dates d
where
b.basedate <= d.dt
return
end
go





-- test for various months
select * from shifts(1,2007) order by empid,date
select * from shifts(2,2007) order by empid,date
select * from shifts(3,2007) order by empid,date
select * from shifts(4,2007) order by empid,date
select * from shifts(5,2007) order by empid,date
select * from shifts(12,2007) order by empid,date






profquail
Starting Member

5 Posts

Posted - 2007-12-08 : 21:29:11
Well, at least for the number of days in the month (your first question), it's pretty simple. Just declare an int variable and select something like this into it:

CASE WHEN MONTH(@pDate) IN (1, 3, 5, 7, 8, 10, 12) THEN 31
WHEN MONTH(@pDate) IN (4, 6, 9, 11) THEN 30
ELSE CASE WHEN (YEAR(@pDate) % 4 = 0 AND
YEAR(@pDate) % 100 != 0) OR
(YEAR(@pDate) % 400 = 0)
THEN 29
ELSE 28
END
END


I found this at:
http://www.sql-server-helper.com/functions/get-days-in-month.aspx
Go to Top of Page

Vinnie881
Master Smack Fu Yak Hacker

1231 Posts

Posted - 2007-12-09 : 02:06:37
your function is very confusing. can you please shorten your quetion and post your desired results.
Go to Top of Page

ilan
Starting Member

21 Posts

Posted - 2007-12-09 : 03:14:00
this function working ok whan spliting the employee shift value (1,1,2,2,3,3,4,5) .
but for the "UNIT" value for
the employee i need that value "UNIT" the value(1,2,3,4)
change evry first day in the month the "1" and only in the first day in the month !!
need to add another field date for the unit
so whan i need to change the "UNIT" value for the employee in the first day in the month
this function take the value date from the the new date call "UNIT_DATE"
like this thre no connection between "UNIT_DATE" and "basedate"
field "basedate" for the shift value (1,1,2,2,3,3,4,5)
field "Unit_date" for the UNIT value (1,2,3,4)

TNX
Go to Top of Page

Vinnie881
Master Smack Fu Yak Hacker

1231 Posts

Posted - 2007-12-10 : 00:41:34
Let's do this.

Post your table structure, then post what you ultimatly want to getr. Skip posting your query, again just post your table, then the desired results. Provide a sample data set that will illustrate both 1st days of the month and anything other that will show your issue.

Your explanation is still not very clear to me.

Go to Top of Page

midan1
Starting Member

39 Posts

Posted - 2007-12-10 : 02:07:20
i am apologize abut my bad English

my problem is with line

((convert(int,(datediff(dd,b.basedate,d.dt) / 30)) % 4) + 1)

the "unit" value
i need to change to the employee evry month the UNIT value
but once a month !! (the first day in the month)

start from 1 to 4(1,2,3,4)
check what was the value in field "UNIT" last month (check date from "unit_date")
if for the employee the value was 1 then 2 if 2 then 3 if 3 then 4
and after from 4 back to 1
my table


insert empbase (empid,basedate,unit_date) values (12345,'2007/1/1','2007/3/1')


can someone help me
tnx
Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2007-12-10 : 02:41:58
[code]declare @i int

select @i = 0

while @i <= 10
begin
print (@i % 4) + 1
select @i = @i + 1
end[/code]


KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

luggi
Starting Member

4 Posts

Posted - 2007-12-10 : 03:32:30
Hi iljan,

You can see the date handling on this page: http://database.ittoolbox.com/pub/TP012003.HTML.

hope that helps you...

cheers,

luggi
Go to Top of Page

midan1
Starting Member

39 Posts

Posted - 2007-12-10 : 03:38:33
quote:
Originally posted by khtan

declare	@i int

select @i = 0

while @i <= 10
begin
print (@i % 4) + 1
select @i = @i + 1
end



KH
tnx but i must to check what was the last unit value last month from the filed "unit_date"
doesn't matter the day in the month
even if it 12/12/2007
or 29/12/2007
check the last month
start a series 1,2,3,4
start from "unit_date"

[spoiler]Time is always against us[/spoiler]



Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2007-12-10 : 03:44:17
quote:
tnx but i must to check what was the last unit value last month from the filed "unit_date"
doesn't matter the day in the month
even if it 12/12/2007
or 29/12/2007
check the last month
start a series 1,2,3,4
start from "unit_date"

that's the part that we don't really understand. What is unit_date ?

1. can you post your table DDL like

create table sample
(
colname int,
. . .
)


2. Provide some sample data of the table

insert into sample values ( . . . )
insert into sample values ( . . . )
insert into sample values ( . . . )


3. show the expected result

col1 col2 col3 col4
xxx xxx xxx xxx
xxx xxx xxx xxx
xxx xxx xxx xxx
xxx xxx xxx xxx



KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2007-12-10 : 06:02:39
First day of the month?
Try SELECT DATEADD(MONTH, DATEDIFF(MONTH, '19000101', CURRENT_TIMESTAMP), '19000101')

Number of days in a month?
Try SELECT DAY(DATEADD(MONTH, DATEDIFF(MONTH, '18991231', CURRENT_TIMESTAMP), '18991231'))


E 12°55'05.25"
N 56°04'39.16"
Go to Top of Page

midan1
Starting Member

39 Posts

Posted - 2007-12-10 : 08:44:26
ok
this is my tb_employee
---------------------------------------------
EMPid basedate unit_date

25555472 01/01/2007 15/02/2007
55555581 01/01/2007 05/03/2007
56555555 01/01/2007 12/06/2007
51555555 01/01/2007 30/07/2007
54655555 01/01/2007 31/07/2007
-------------------------------------------

select * from shifts(1,2007) order by empid,date
-------------------------------------------------
this is the resalt of the functin
-------------------------------------
empid date shift unit
25555472 2007-01-01 1 1
25555472 2007-01-02 1 1
25555472 2007-01-03 2 1
25555472 2007-01-04 2 1
25555472 2007-01-05 3 1
25555472 2007-01-06 3 1
25555472 2007-01-07 4 1
25555472 2007-01-08 5 1

-----------------------------------
how to chack in the tb_employee in filed "unit_date"
the last month that the employee get the value 1
for example this employee (empid=25555472)
in the date 15/02/2007
begin series of unit value (1,2,3,4)
and in date 01/03/2007 the unit value =2(for this employee)
in date 01/04/2007 the unit value =3 (for this employee)
in date 01/05/2007 the unit value=4 (for this employee)
and in the date 01/05/2007 the unit value =1 (for this employee)
2.............3...........4............1
once a month change for employee the unit value from 1 to 2 from 2 to 3 from 3 to 4 and from 4 to 1..........
---------------------------------------------------------
the unit_date value
is a reference to start series of unit value (1,2,3,4)
----------------------------------------------------------

TNX for all wonderful members

Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2007-12-10 : 09:50:06
try to run this see if it is what you want.
using F_TABLE_DATE from http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=61519&SearchTerms=F_TABLE_DATE


DECLARE @tb_employee TABLE
(
empid int,
basedate datetime,
unit_date datetime
)
INSERT INTO @tb_employee
SELECT 25555472, '20070101', '20070215' UNION ALL
SELECT 55555581, '20070101', '20070515' UNION ALL
SELECT 56555555, '20070101', '20070612' UNION ALL
SELECT 51555555, '20070101', '20070730' UNION ALL
SELECT 54655555, '20070101', '20070731'

SELECT e.empid,
d.[DATE],
shift = (row_number() OVER (PARTITION BY e.empid ORDER BY d.[DATE]) + 1) / 2,
unit = DATEDIFF(MONTH, e.unit_date, d.[DATE]) % 4
FROM F_TABLE_DATE('20070501', '20070531') d
INNER JOIN @tb_employee e
ON d.[DATE] >= e.unit_date
ORDER BY e.empid, d.[DATE]



KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

midan1
Starting Member

39 Posts

Posted - 2007-12-10 : 17:40:14
tnx men for the help
i test it and run this functin
it not work ok see !!
i don't have a shift value 16 6 7 8 9
and the unit value not change evry month (from 1,2,3,4)
-----------------
25555472 2007-05-31 00:00:00.000 16 3
55555581 2007-05-15 00:00:00.000 1 0
55555581 2007-05-16 00:00:00.000 1 0
55555581 2007-05-17 00:00:00.000 2 0
55555581 2007-05-18 00:00:00.000 2 0
55555581 2007-05-19 00:00:00.000 3 0
55555581 2007-05-20 00:00:00.000 3 0
55555581 2007-05-21 00:00:00.000 4 0
55555581 2007-05-22 00:00:00.000 4 0
55555581 2007-05-23 00:00:00.000 5 0
55555581 2007-05-24 00:00:00.000 5 0
55555581 2007-05-25 00:00:00.000 6 0
55555581 2007-05-26 00:00:00.000 6 0
55555581 2007-05-27 00:00:00.000 7 0
55555581 2007-05-28 00:00:00.000 7 0
55555581 2007-05-29 00:00:00.000 8 0
55555581 2007-05-30 00:00:00.000 8 0
55555581 2007-05-31 00:00:00.000 9 0
Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2007-12-10 : 22:17:49
[code]DECLARE @tb_employee TABLE
(
empid int,
basedate datetime,
unit_date datetime
)
INSERT INTO @tb_employee
SELECT 25555472, '20070101', '20070215' UNION ALL
SELECT 55555581, '20070101', '20070515' UNION ALL
SELECT 56555555, '20070101', '20070612' UNION ALL
SELECT 51555555, '20070101', '20070730' UNION ALL
SELECT 54655555, '20070101', '20070731'

SELECT e.empid,
d.[DATE],
shift = ((row_number() OVER (PARTITION BY e.empid ORDER BY d.[DATE]) - 1) % 16 + 2) / 2,
unit = (DATEDIFF(MONTH, e.unit_date, d.[DATE])% 4) + 1
FROM F_TABLE_DATE('20070501', '20070531') d
INNER JOIN @tb_employee e
ON d.[DATE] >= e.unit_date
ORDER BY e.empid, d.[DATE]

empid DATE shift unit
----------- ----------- ------- -----
25555472 2007-05-01 1 4
25555472 2007-05-02 1 4
25555472 2007-05-03 2 4
25555472 2007-05-04 2 4
25555472 2007-05-05 3 4
25555472 2007-05-06 3 4
25555472 2007-05-07 4 4
25555472 2007-05-08 4 4
25555472 2007-05-09 5 4
25555472 2007-05-10 5 4
25555472 2007-05-11 6 4
25555472 2007-05-12 6 4
25555472 2007-05-13 7 4
25555472 2007-05-14 7 4
25555472 2007-05-15 8 4
25555472 2007-05-16 8 4
25555472 2007-05-17 1 4
25555472 2007-05-18 1 4
25555472 2007-05-19 2 4
25555472 2007-05-20 2 4
25555472 2007-05-21 3 4
25555472 2007-05-22 3 4
25555472 2007-05-23 4 4
25555472 2007-05-24 4 4
25555472 2007-05-25 5 4
25555472 2007-05-26 5 4
25555472 2007-05-27 6 4
25555472 2007-05-28 6 4
25555472 2007-05-29 7 4
25555472 2007-05-30 7 4
25555472 2007-05-31 8 4
55555581 2007-05-15 1 1
55555581 2007-05-16 1 1
55555581 2007-05-17 2 1
55555581 2007-05-18 2 1
55555581 2007-05-19 3 1
55555581 2007-05-20 3 1
55555581 2007-05-21 4 1
55555581 2007-05-22 4 1
55555581 2007-05-23 5 1
55555581 2007-05-24 5 1
55555581 2007-05-25 6 1
55555581 2007-05-26 6 1
55555581 2007-05-27 7 1
55555581 2007-05-28 7 1
55555581 2007-05-29 8 1
55555581 2007-05-30 8 1
55555581 2007-05-31 1 1

(48 row(s) affected)
*/

[/code]


KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

midan1
Starting Member

39 Posts

Posted - 2007-12-11 : 08:30:11
khtan you are genius
tnx men WOW

my question please
1) can i convert this to function
like this
-----------------------------------------------
select * from shifts(1,2007) order by empid,date
--------------------------------------------------

2)can i put only the month only like (12/2007)
insted of ('20071201', '20071231')
because thre is problem in month with 31,30,29,28 days

again many TNX for your help


Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2007-12-11 : 08:43:54
use these to get the 1st and last day of the month / year

declare @year	int,
@month int

select @year = 2007,
@month = 2

select [1st of month] = dateadd(year, @year - 1900, dateadd(month, @month - 1, 0)),
[last of month] = dateadd(year, @year - 1900, dateadd(month, @month, -1))



KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

midan1
Starting Member

39 Posts

Posted - 2007-12-11 : 17:49:19
ok tnx
what to do with the "Function F_TABLE_DATE"
in this line
FROM F_TABLE_DATE('20070501', '20070531') d
do i must to use the "Function F_TABLE_DATE"
tnx
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2007-12-11 : 17:58:05
Any other date generating function will do.
Or if you already have a date table stored.



E 12°55'05.25"
N 56°04'39.16"
Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2007-12-11 : 20:27:22
F_TABLE_DATE is an excellent function that generate a lists of dates from specified start and end date range. Basically it does the same thing as what you are doing with your cross join of d1, d2 etc. But it provide more information than just DATE.


KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page
   

- Advertisement -