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.
Author |
Topic |
ilan
Starting Member
21 Posts |
Posted - 2007-12-08 : 13:53:05
|
need help with this function !first prolemthis 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 monthsecond problemhow 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 unitso i can fill the table like thisinsert empbase (empid,basedate,unit_date) values (12345,'2007/1/1','2007/3/1')like this i can 1) set date for "basedate" start DATE2)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" referencelike 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 datainsert 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_vartable (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.begindeclare @d1 datetimedeclare @d31 datetimeset @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 d1cross joinn01 as d2cross joinn01 as d3cross joinn01 as d4cross joinn01 as d5),dates (dt) as (selectdateadd(dd,n,@d1) as 'dt'fromseqwheredateadd(dd,n,@d1) <= @d31),modval (mod,val) as (select 0,1 union allselect 1,1 union allselect 2,2 union allselect 3,2 union allselect 4,3 union allselect 5,3 union allselect 6,4 union allselect 7,5)insert @table_varselectb.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)fromempbase b, dates dwhereb.basedate <= d.dtreturnendgo-- test for various monthsselect * from shifts(1,2007) order by empid,dateselect * from shifts(2,2007) order by empid,dateselect * from shifts(3,2007) order by empid,dateselect * from shifts(4,2007) order by empid,dateselect * from shifts(5,2007) order by empid,dateselect * 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 ENDI found this at:http://www.sql-server-helper.com/functions/get-days-in-month.aspx |
|
|
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. |
|
|
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 forthe 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 unitso whan i need to change the "UNIT" value for the employee in the first day in the monththis 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 |
|
|
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. |
|
|
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" valuei need to change to the employee evry month the UNIT valuebut 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 4and after from 4 back to 1my tableinsert empbase (empid,basedate,unit_date) values (12345,'2007/1/1','2007/3/1') can someone help metnx |
|
|
khtan
In (Som, Ni, Yak)
17689 Posts |
Posted - 2007-12-10 : 02:41:58
|
[code]declare @i intselect @i = 0while @i <= 10begin print (@i % 4) + 1 select @i = @i + 1end[/code] KH[spoiler]Time is always against us[/spoiler] |
|
|
luggi
Starting Member
4 Posts |
|
midan1
Starting Member
39 Posts |
Posted - 2007-12-10 : 03:38:33
|
quote: Originally posted by khtan
declare @i intselect @i = 0while @i <= 10begin print (@i % 4) + 1 select @i = @i + 1end KHtnx 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 montheven if it 12/12/2007or 29/12/2007check the last monthstart a series 1,2,3,4 start from "unit_date" [spoiler]Time is always against us[/spoiler]
|
|
|
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 montheven if it 12/12/2007or 29/12/2007check the last monthstart a series 1,2,3,4start from "unit_date"
that's the part that we don't really understand. What is unit_date ?1. can you post your table DDL likecreate table sample( colname int, . . . ) 2. Provide some sample data of the tableinsert into sample values ( . . . )insert into sample values ( . . . )insert into sample values ( . . . ) 3. show the expected resultcol1 col2 col3 col4xxx xxx xxx xxxxxx xxx xxx xxxxxx xxx xxx xxxxxx xxx xxx xxx KH[spoiler]Time is always against us[/spoiler] |
|
|
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" |
|
|
midan1
Starting Member
39 Posts |
Posted - 2007-12-10 : 08:44:26
|
okthis is my tb_employee---------------------------------------------EMPid basedate unit_date25555472 01/01/2007 15/02/200755555581 01/01/2007 05/03/200756555555 01/01/2007 12/06/200751555555 01/01/2007 30/07/200754655555 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 unit25555472 2007-01-01 1 125555472 2007-01-02 1 125555472 2007-01-03 2 125555472 2007-01-04 2 125555472 2007-01-05 3 125555472 2007-01-06 3 125555472 2007-01-07 4 125555472 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 1for example this employee (empid=25555472)in the date 15/02/2007begin 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............1once 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 valueis a reference to start series of unit value (1,2,3,4)---------------------------------------------------------- TNX for all wonderful members |
|
|
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_employeeSELECT 25555472, '20070101', '20070215' UNION ALLSELECT 55555581, '20070101', '20070515' UNION ALLSELECT 56555555, '20070101', '20070612' UNION ALLSELECT 51555555, '20070101', '20070730' UNION ALLSELECT 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]) % 4FROM F_TABLE_DATE('20070501', '20070531') d INNER JOIN @tb_employee e ON d.[DATE] >= e.unit_dateORDER BY e.empid, d.[DATE] KH[spoiler]Time is always against us[/spoiler] |
|
|
midan1
Starting Member
39 Posts |
Posted - 2007-12-10 : 17:40:14
|
tnx men for the helpi test it and run this functinit not work ok see !!i don't have a shift value 16 6 7 8 9and the unit value not change evry month (from 1,2,3,4)-----------------25555472 2007-05-31 00:00:00.000 16 355555581 2007-05-15 00:00:00.000 1 055555581 2007-05-16 00:00:00.000 1 055555581 2007-05-17 00:00:00.000 2 055555581 2007-05-18 00:00:00.000 2 055555581 2007-05-19 00:00:00.000 3 055555581 2007-05-20 00:00:00.000 3 055555581 2007-05-21 00:00:00.000 4 055555581 2007-05-22 00:00:00.000 4 055555581 2007-05-23 00:00:00.000 5 055555581 2007-05-24 00:00:00.000 5 055555581 2007-05-25 00:00:00.000 6 055555581 2007-05-26 00:00:00.000 6 055555581 2007-05-27 00:00:00.000 7 055555581 2007-05-28 00:00:00.000 7 055555581 2007-05-29 00:00:00.000 8 055555581 2007-05-30 00:00:00.000 8 055555581 2007-05-31 00:00:00.000 9 0 |
|
|
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_employeeSELECT 25555472, '20070101', '20070215' UNION ALLSELECT 55555581, '20070101', '20070515' UNION ALLSELECT 56555555, '20070101', '20070612' UNION ALLSELECT 51555555, '20070101', '20070730' UNION ALLSELECT 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) + 1FROM F_TABLE_DATE('20070501', '20070531') d INNER JOIN @tb_employee e ON d.[DATE] >= e.unit_dateORDER 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] |
|
|
midan1
Starting Member
39 Posts |
Posted - 2007-12-11 : 08:30:11
|
khtan you are genius tnx men WOWmy question please1) 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 daysagain many TNX for your help |
|
|
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 / yeardeclare @year int, @month intselect @year = 2007, @month = 2select [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] |
|
|
midan1
Starting Member
39 Posts |
Posted - 2007-12-11 : 17:49:19
|
ok tnxwhat to do with the "Function F_TABLE_DATE" in this lineFROM F_TABLE_DATE('20070501', '20070531') ddo i must to use the "Function F_TABLE_DATE" tnx |
|
|
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" |
|
|
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] |
|
|
|
|
|
|
|