Welcome to the dBforums forums.

You are currently viewing our boards as a guest which gives you limited access to view most discussions, articles and access our other FREE features. By joining our free community you will have access to post topics, communicate privately with other members (PM), respond to polls, upload your own photos and access many other special features. Registration is fast, simple and absolutely free so please, join our community today!

If you have any problems with the registration process or your account login, please contact contact support.

If you prefer not to see double-underlined words and corresponding ads, place your cursor
here for ContentLink opt out.

Go Back  dBforums > Database Server Software > PostgreSQL > Calculation based on none work day (sat sun) ?

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old 11-29-07, 08:12
MercJones MercJones is offline
Registered User
 
Join Date: Nov 2007
Posts: 6
Calculation based on none work day (sat sun) ?

Hi there.

Been scatching my head for a bit with this now, and cant find an easy solution, or pretty much any solution..

Im moving from MSSQL - Postgresql. the query in MSSQL was:

SELECT Now()-([DateOrdered])-1.2 AS Expr1 .....

and

WHERE ((Now()-([DateOrdered])-1.2)>6) ...


so the basic idea is work out if dateordered > 6 days, but take away the 2 non-working days weekends.

So i need to do:

WHERE NOW() - dateordered(APART FROM SAT SUN) > 6.. but dont know how to do it.

I can find the day of a certain date using SELECT extract(dow from dateordered); which will give me 1-6 0 being sunday, 1 being monday for example.

Any ideas how I can put all this together though?

I could use php if it cant be done just in a query.

Cheers
Reply With Quote
  #2 (permalink)  
Old 11-29-07, 12:10
loquin loquin is offline
Super Moderator
 
Join Date: Jun 2004
Location: Arizona, USA
Posts: 1,359
Now() is supported in pg - it is equivalent to the Current_timestamp function. You may want to use current_date instead.

Also, try changing the 1.2 to interval '1 days 4 hours 48 minutes'


Now, I BELIEVE the AGE function will do MOST of what you want.
You could also try

Code:
Where Age(dateordered) - interval '1 days 4 hours 48 minutes' > interval '6 days'

The key thing to remember is that PostgreSQL is, on the whole, more strongly typed than is MSSQL. (It doesn't make many assumptions - it requires you to explicitly perform conversion functions as needed)

Ref http://www.postgresql.org/docs/8.2/s...-datetime.html
__________________
Lou
使大吃一惊
"Lisa, in this house, we obey the laws of thermodynamics!" - Homer Simpson
"I have my standards. They may be low, but I have them!" - Bette Middler
"It's a book about a Spanish guy named Manual. You should read it." - Dilbert


Last edited by loquin : 11-29-07 at 12:26.
Reply With Quote
  #3 (permalink)  
Old 11-29-07, 12:18
amthomas amthomas is offline
Registered User
 
Join Date: May 2005
Location: San Antonio, Texas
Posts: 134
hehe, I was just looking at that same page

I am not sure about the ignoring sat/sun part. someone may have a cool way of dealing with that but I would probably script in whatever language.

Also note that you can play around with interval a lot os loquin noted, and then use extract(field from interval) to get the values out.
__________________
Vi veri veniversum vivus vici
By the power of truth, I, a living man, have conquered the universe
Reply With Quote
  #4 (permalink)  
Old 11-29-07, 12:55
loquin loquin is offline
Super Moderator
 
Join Date: Jun 2004
Location: Arizona, USA
Posts: 1,359
Probably the simplest database approach would be to add a calendar table, containing two fields - a date field, and an integer field. The date field would contain all dates, including weekends and holidays, between the minimum working date and the maximum working date. (+20/-10 years worth, for instance,) indexed by the date. (If you need to hold down the size of the table, limit the date range and periodically flush old days and add new ones)

The integer field would contain a zero (0) if the date is a weekend or holiday, and a 1 if the date is a working day (weekday, non-holiday)

To calculate the number of working days between any two two dates from the calendar table, simply sum the integer field between the start and end dates.
__________________
Lou
使大吃一惊
"Lisa, in this house, we obey the laws of thermodynamics!" - Homer Simpson
"I have my standards. They may be low, but I have them!" - Bette Middler
"It's a book about a Spanish guy named Manual. You should read it." - Dilbert


Last edited by loquin : 11-29-07 at 13:00.
Reply With Quote
  #5 (permalink)  
Old 11-29-07, 12:56
MercJones MercJones is offline
Registered User
 
Join Date: Nov 2007
Posts: 6
Thanks for the info guys.

Ive spent a while looking at the stuff today and came up with:

select (now()::date - dateordered::date) as daysold,orders.dateordered, orders.jobnumber from (staff inner join orders on staff.staffnumber = orders.staffordering) inner join customers on orders.customerid = customers.customerid where extract(dow from dateordered)::int % 6 > 0 AND (dateordered < now() - '5 day'::interval) AND ((orders.requesteddispatchdate < now()) OR (orders.requesteddispatchdate IS NULL)) AND (orders.completed_order = 'f') AND (orders.confirmedorder = 't');

which works.. but my flaw is that if you have a dateordered over 5 days old, that was ordered on a sat or sun.. it doesnt show up. ARGH.

so have then tried:

select (now()::date - dateordered::date) as daysold,orders.dateordered, orders.jobnumber from (staff inner join orders on staff.staffnumber = orders.staffordering) inner join customers on orders.customerid = customers.customerid where Age(dateordered) - interval '1 days 4 hours 48 minutes' > interval '6 days' AND ((orders.requesteddispatchdate < now()) OR (orders.requesteddispatchdate IS NULL)) AND (orders.completed_order = 'f') AND (orders.confirmedorder = 't');

which runs, but i still cant work out if its missing orders?

It needs to show all jobs that are overdue, if they are greater than 5 days not including sat/sun (show the job) or if its > say 7 days, show all...

stuck again lol
Reply With Quote
  #6 (permalink)  
Old 11-29-07, 16:23
loquin loquin is offline
Super Moderator
 
Join Date: Jun 2004
Location: Arizona, USA
Posts: 1,359
OK.

create a table called "workdays" on your database, with date field 'workdate' (pk) and integer field 'workday'

copy the attached csv file to your server.

run the script below to import the csv file to your new table. (use your actual pathname where you saved the csv file)

Code:
copy tds.workdays (workdate, workday) from 'c:\\workdays.txt' delimiter ',' csv header
(Note the double '\' escaping)

Now, try the following query
Code:
Select Sum (workday) as WorkingDays from workdays where workdate > '10-17-2007' and workdate <= '10-25-2007'

Although you could use this as a subquery in a where clause, I would write a function to return the number of working days between Date1 and Date2 - it would result in simpler, more efficient queries.

Another advantage of this approach is that you only need to update the workday value for a given date in order to set that date as a holiday or other non-work day.

At my location, we've extended this approach to handle our non-standard work week. I added a column workhours, as we work a 9/80 schedule. In a two week period, we work a total of 9 days, and 80 hours, (Week1: M, T, W, T at 9 hours, F at 8 hours; Week2: M, T, W, T at 9 hours, F off.) This schedule means that we need to search by the number of working hours, rather than days.
Attached Files
File Type: txt WorkDays.txt (235.7 KB, 71 views)
__________________
Lou
使大吃一惊
"Lisa, in this house, we obey the laws of thermodynamics!" - Homer Simpson
"I have my standards. They may be low, but I have them!" - Bette Middler
"It's a book about a Spanish guy named Manual. You should read it." - Dilbert


Last edited by loquin : 11-29-07 at 16:45.
Reply With Quote
  #7 (permalink)  
Old 11-30-07, 06:32
MercJones MercJones is offline
Registered User
 
Join Date: Nov 2007
Posts: 6
Hi mate, great reply there, still having issues but appreciate the help.

Ive created that table, and added all the dates etc so if my existing query is:

select (now()::date - dateordered::date) as daysold,orders.dateordered, orders.jobnumber from (staff inner join orders on staff.staffnumber = orders.staffordering) inner join customers on orders.customerid = customers.customerid where extract(dow from dateordered)::int % 6 > 0 AND (dateordered < now() - '5 day'::interval) AND ((orders.requesteddispatchdate < now()) OR (orders.requesteddispatchdate IS NULL)) AND (orders.completed_order = 'f') AND (orders.confirmedorder = 't');

i cant see how I can replace

select (now()::date - dateordered::date) as daysold (i think it would be select sum(workday) as workingdays from workdays where workdate = now() - dateordered) but I think it may need an alias?

that bit works as it is, but the part that im really confused about is replacing:

extract(dow from dateordered)::int % 6 > 0 AND (dateordered < now() - '5 day'::interval)


that works, but not right... i think ive got my logic wrong, but now that workdays table exists it should be tons easier.. but the issue is i need to be able to get results of overdue jobs where if the dateordered > 5 days, not including weekends INCLUDE THAT RESULT, but..(the part im missing *i think*) if its over 5 days old, include it anyway. does that make sense?


Cheers again for the help, really close now I think
Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On