I simply want to combine the total years of service from various members of my team. The below script works fine, however, the hire date for each member does not pull from a database. Which means I have to hard code each persons hiredate and then do a DateDiff on them. With a team of 28 members that would cause a code management nightmare.
My main goal is to make the code simpler and more efficient, especially when managing 28 team members. If part of the path requires adding the user's hiredate to a database; I can do that. I just see the code below needing a rewrite, I just don't know the best method.
Is there a better way?
<cfscript>
REQUEST.rightnow = Now();
dateBob = DateDiff("yyyy", "1996 02 01", REQUEST.rightnow);
dateSam = DateDiff("yyyy", "1996 08 01", REQUEST.rightnow);
dateJoe = DateDiff("yyyy", "2004 12 01", REQUEST.rightnow);
dateJohn = DateDiff("yyyy", "2001 01 01", REQUEST.rightnow);
combinedDate = (dateBob + dateSam + dateJoe + dateJohn);
</cfscript>
<cfoutput>
#combinedDate# total years<br>
#dateBob# years<br>
#dateSam# years<br>
#dateJoe# years<br>
#dateJohn# years<br>
</cfoutput>
--- EDIT ---
Per Matt's suggestion as a database query; something like this?
SELECT hire_date,
ROUND((DATEDIFF(NOW(),hire_date)) / 365) AS dateDiff
FROM members
WHERE hire_date IS NOT NULL
--- EDIT 2 ---
I just realised I forgot to add SUM() of all the "dateDiff". If anyone uses this SQL you will have to hand it off to ColdFusion, I suppose. Unless I overlooked a way to do it in SQL?
--- EDIT 3 ---
Per Leigh's comments of encouragement; I found a better way. The TIMESTAMPDIFF() MySQL function adds a unit variable that can be day, month, year, etc. This allowed me to remove the / 365 and the ROUND(). Which in turn allowed me to use SUM() and not get a syntax error from MySQL. I also renamed my alias from dateDiff to just Dif because I wanted to avoid confusion with DATEDIFF().
See below. :D
SELECT hire_date,
SUM(TIMESTAMPDIFF(YEAR,hire_date,NOW())) AS Dif
FROM members
WHERE hire_date IS NOT NULL
The solution to improving the code posted for ColdFusion was actually replacing it. By adding the hire_dates of each member to an existing MySQL database and writing the query below; I no longer needed all of the ColdFusion code in my original post.
SELECT SUM(TIMESTAMPDIFF(YEAR,hire_date,NOW())) AS Dif
FROM members
WHERE hire_date IS NOT NULL
Related
I have an issue writing a query in MS Access that would pull information from two tables.
Quick description:
Employees start the job and click the button in Excel macro. The macro saves the date and a comment that the employee provides (not required). Next, the macro pushes the information into a table in Access database which gathers all 'check-ins' of all employees. There's a possibility for a person to check-in twice by accident. This is an example how the table would look like after two work days, in a company with three employees:
check-in table example
Similarly, the macro lets a user to check-out, also with optional comment:
check-out table example
What I need is a query that would consolidate two of these tables and show check-in/check-out of employees for a previous day, together with provided comment. So the result of the query would look like this:
outcome of a table for previous day
Column order is absolutely irrelevant here
SELECT min(checkin.[check-in time]), max(checkout.[check-out time]), checkin.[comment] AS [check-in comment], checkout.[comment] AS [check-out comment]
FROM checkin
RIGHT JOIN chekout ON checkin.analyst = checkout.analyst
WHERE checkin[check-in time] = Date()-3;
Bad thing is, MS Access throws:
Syntax error in JOIN operation
Could anyone help me out and advise how should I proceed? Unfortunately I have no control how the system was implemented (Macro in Excel connected with Access) and sadly I have not much experience in MS Access.
EDIT:
Thank you very much #Erik, much appreciated. It helped a lot and I'll be more diligent next time when it comes to typos. The new problem presented itself however. It is possible for a person to check-in, without checking-out and vice versa. Lets say there's another row in the first table -> Meg015 checked in at 7:20 on 08.06.2018 but forgot to check out:
see an example
I would like MS Access to present this information accordingly (without forgotten check-out time):
How it should look like
Since there's no Full Outer Join in MS Access, I was thinking about following UNION/LEFT and RIGHT JOINs:
SELECT checkin.analyst, min(checkin.[check-in time]), max(checkout.[check-out time]), checkin.comment, checkout.comment
FROM checkin RIGHT JOIN checkout ON (checkin.analyst = checkout.analyst OR checkout.analyst = NULL OR checkin.analyst = NULL)
WHERE (format(checkin.[check-in time], "Short Date") = format(checkout.[check-out time], "Short Date") OR checkout.[check-out time] = NULL) AND format(checkin.[check-in time], "Short Date") = date()-3
GROUP BY checkin.analyst, checkin.comment, checkout.comment
UNION
SELECT checkout.analyst, min(checkin.[check-in time]), max(checkout.[check-out time]), checkin.comment, checkout.comment
FROM checkin LEFT JOIN checkout ON (checkin.analyst = checkout.analyst OR checkin.analyst = NULL OR checkout.analyst = NULL)
WHERE (format(checkin.[check-in time], "Short Date") = format(checkout.[check-out time], "Short Date") OR checkin.[check-in time] = NULL) AND format(checkin.[check-in time], "Short Date") = date()-3
GROUP BY checkout.analyst, checkin.comment, checkout.comment;
Sadly, Meg's check-in details are not visible in a result of the query above. Any idea how to resolve this issue?
You're missing a dot, have misspelt checkout in your join, and are using aggregates without grouping by the other columns.
Also, you're testing if a date is equal to a date with time, which will pretty much always be false.
Anyway, this is how your query should look like:
SELECT checkout.analyst, min(checkin.[check-in time]), max(checkout.[check-out time]), checkin.[comment] AS [check-in comment], checkout.[comment] AS [check-out comment]
FROM checkin
RIGHT JOIN checkout ON checkin.analyst = checkout.analyst
WHERE DATEDIFF('d',checkin.[check-in time], Date()) = 3
GROUP BY checkout.analyst, checkout.[comment], checkin.[comment]
(Do note that questions with this many errors can get closed as too broad).
I'm trying to setup a query that will show me all of the records in a particular table where the listed expiry date is either in the past or upcoming in the next 6 months (approximately).
At the moment, I have the "Expiry" field added to my query and the 'Criteria' as .
When I try to save the query, I get the following message:
Access can't evaluate an expression or convert data because data types aren't compatible with each other.
TECHNICAL DETAILS
Correlation ID: ae68949d-3041-3000-0984-71635f8fd670
Date and Time: 7/28/2016 6:54:34 PM
I've tried searching the web for a solution, but most websites refer to the Date() function that doesn't seem to be available in the Access 2016 Custom Web App. When I take out the "+180", it works fine but obviously doesn't give me what I need.
Any help would be appreciated.
=============================
UPDATE:
Some users have asked for my SQL and Table Design details. I don't seem to have any way of accessing the SQL View (the option doesn't appear), but here's a copy of my table view:
Access Query Table Design
In the table, 'Active' is a Yes/No field and 'Expiry' is Date/Time.
Try
< DateAdd(Day, 180, Today())
as criteria.
According to https://msdn.microsoft.com/en-us/library/office/jj249452.aspx this should work in a custom web app.
Error says that you have two different date types and they can't be compared. so, as the Today() returns only the Date with 12:00 pm, I can guess that your other "Expiry" Field is a datetime type. So, you can do either: use Format function to convert datetime to date like this
Format([2/22/2012 12:00 PM],"dd/mm/yyyy")
or use Now() function which returns datetime,
or Share your Code :)
How can I tell Access once & for all that I am in Belfast UK and not Belfast ME? To illustrate my problem, I have created a table containing the dates of each day in 2012. If I run this query
SELECT *
FROM tblListOfDays
WHERE dtmDay BETWEEN #01/05/2012# AND #31/05/2012#
148 rows are returned, all the dates from 5th January to 31st May. So Access is reading one date in US format, and the other (presumably because it is has no choice) as UK format. If I use
Format("01/05/2012", "dd/MM/yyyy")
instead of
01/05/2012
then I get the answer I want, but surely there is a simpler way than having to use Format all the time? All my regional/locale settings are UK as far as I can check.
as petr-abdulin said you can use
Format(expression, format)
So your code becam :
SELECT * FROM tblListOfDays WHERE Format(dtmDay, "dd-mm-yyyy") BETWEEN
Format("01/05/2012", "dd-mm-yyyy") AND Format("31/05/2012", "dd-mm-yyyy")
and dont forget to use format while inserting also.
and here you can find more info about this function.
AFAIK there is no other way than to specify date format explicitly using Format function.
I run a web design firm, and we also sell hosting on a yearly basis to our customers. I'm writing a Ruby script to read all of the customers from a MySQL database and check to see if a year has passed. If it has (or is at least close to expiring), I want it to send an Email to them.
I have the Emailing part down, but how would I check to see if one year has passed using the Time class, or another solution based in SQL?
(looking back with this edit, it seems as though I don't quite know the SQL needed, so any help on that is appreciated)
If you really want to solve this issue using ruby you can use >> when dealing with a Date to increment it by N months (such as 11, which will give your customers some time to deal with the payment).
When you've got this incremented date you should compare it to what the current date is to see if it's less or equal (ie. the date is in the past), if so; send out your email.
>> (Date.strptime('2012-07-07') >> 11).to_s
=> "2013-06-07"
>> if (Date.strptime('2011-06-15') >> 11) < DateTime.now
>> print "More than 11 months has passed!"
>> end
More than 11 months has passed!=> nil
Though, you are much better of solving this issue directly in the SQL query, which would boil down to something as the below:
SELECT field1, field2, ..., fieldN
FROM `customers_table`
WHERE ADDDATE(last_payment, INTERVAL 11 MONTHS) <= NOW ()
In my database i have month name as january, february, march like that.
I represent field name is text. When i execute the select query with order by month field month, it will provide the output as february, january like that.
I know it is clear by the FORMAT or db field representation. Though i am new to the ms access so i don't know the correct format for this. Please help me.
You will have to create your own custom function in a module that cnverts the value for you.
Something like
Public Function StrToMonth(strIn As String) As Integer
Dim arrMonth(12) As Variant
Dim i As Integer
arrMonth(0) = "January"
arrMonth(1) = "February"
arrMonth(2) = "March"
arrMonth(3) = "April"
arrMonth(4) = "May"
arrMonth(5) = "June"
arrMonth(6) = "July"
arrMonth(7) = "August"
arrMonth(8) = "September"
arrMonth(9) = "October"
arrMonth(10) = "November"
arrMonth(11) = "December"
For i = 0 To UBound(arrMonth) - 1
If strIn = arrMonth(i) Then
StrToMonth = i + 1
Exit Function
End If
Next i
End Function
And then you can use it in your queries like
SELECT Table1.MonthVal
FROM Table1
ORDER BY StrToMonth([MonthVal]);
Add an additional column to the table(s) with month names that have the month-number-in-year, or much better, don't store months as strings, instead store them as dates e.g. 1 August 2010, which will make this problem considerably easier to solve.
Store the months as integers as currently your rows are returned using alpabetic sorting (how should database know that these strings there are months?): April, August, February, January, March...
You can convert the month to a date for the purpose of sorting:
SELECT MonthName
FROM SomeTable
ORDER BY CDate("1/" & [MonthName] & "/2010");
If you've decided it's inappropriate to store the months as actual dates (and it certainly could be -- I'm not criticizing that decision), you want to maximize performance by storing your data in a format that is most efficient.
That is most likely storing the month as an integer.
For display purposes, say in reports, or on a form, you can display the month name using format. It's a little tricky, as there's no direct conversion (where "MonthField" refers to the field where you're storing the month integer):
Format(DateSerial(Year(Date()), MonthField, 1), "mmmm")
An alternative would be to have a table that maps a month integer to the month name, but that adds a join, and if the field can be blank, you'd have to have an outer join, and that's much more expensive performance-wise than an inner join.
Keep in mind that you'd use the Format() statement only in the presentation layer, i.e., as the controlsource of a control on a form or report. On forms you'd likely use a 2-column combo box for this purpose, so the user would see the month name, but the value stored would actually be the month integer. In that case, a table might make sense, but I'm not certain that it would have any real advantage over just typing in a value list -- it's not like this is volatile data, i.e., data that may need to be edited (which is the main reason you'd use a table in place of a value list)!
EDIT:
As #HansUp has pointed out, there's a MonthName() function in VBA (I didn't know it existed!), so that makes all the above way more complicated than it needs to be -- you could use that in the presentation layer without a need for a table or for the complicated Format() statement.