| 
                
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 |  
                                    | ilanStarting 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 |  |  
                                    | profquailStarting 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 |  
                                          |  |  |  
                                    | Vinnie881Master 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. |  
                                          |  |  |  
                                    | ilanStarting 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 |  
                                          |  |  |  
                                    | Vinnie881Master 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. |  
                                          |  |  |  
                                    | midan1Starting 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 table insert empbase (empid,basedate,unit_date) values (12345,'2007/1/1','2007/3/1')can someone help metnx |  
                                          |  |  |  
                                    | khtanIn (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]
 |  
                                          |  |  |  
                                    | luggiStarting Member
 
 
                                    4 Posts |  |  
                                    | midan1Starting 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]
 
 |  
                                          |  |  |  
                                    | khtanIn (Som, Ni, Yak)
 
 
                                    17689 Posts | 
                                        
                                          |  Posted - 2007-12-10 : 03:44:17 
 |  
                                          | quote:that's the part that we don't really understand. What is unit_date ?1. can you post your table DDL liketnx 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"
 
 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   col4xxx    xxx    xxx    xxxxxx    xxx    xxx    xxxxxx    xxx    xxx    xxxxxx    xxx    xxx    xxx KH[spoiler]Time is always against us[/spoiler]
 |  
                                          |  |  |  
                                    | SwePesoPatron 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"
 |  
                                          |  |  |  
                                    | midan1Starting 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 |  
                                          |  |  |  
                                    | khtanIn (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]
 |  
                                          |  |  |  
                                    | midan1Starting 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 |  
                                          |  |  |  
                                    | khtanIn (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]
 |  
                                          |  |  |  
                                    | midan1Starting 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 |  
                                          |  |  |  
                                    | khtanIn (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	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]
 |  
                                          |  |  |  
                                    | midan1Starting 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 |  
                                          |  |  |  
                                    | SwePesoPatron 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"
 |  
                                          |  |  |  
                                    | khtanIn (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]
 |  
                                          |  |  |  
                                |  |  |  |  |  |