This might be simple but my brain has melted after a long day of non stop coding, and I'm running out of paper fast...
I'm trying to figure out a yearly expiry formula to calculate in a stored procedure.
Simplified table:
Security_Table
-----------------
User_ID [int]
Join_Date [DateTime]
Expired [VARCHAR]
So if a user joined on 2010-01-11 Expired would update to "TRUE" today, same goes for someone who joined on 2009-01-11 as it's a recurring expiry.
I'm running the procedure on a daily basis through scheduled tasks, would comparing the day and month be suffice? Obviously accounting for a leap year.
UPDATE Security_Table SET Expired = 'TRUE' WHERE DATE_FORMAT(Join_Date,'%m-%d') = DATE_FORMAT(NOW(),'%m-%d')
Thanks guys.
Yes, you can use WHERE month = month and date = date. (Though be careful of 29th Feb as a join date.)
This does, however, mean you have to scan to whole table/index looking for matches. If you have a large table, this may be a problem.
I would think that in this case you're better off setting an expiry date value. Then checking that...
WHERE
expiry_date <= CURDATE()
When some-one renews you can update the expiry. SET expiry_date = DATE_ADD(expiry_date, INTERVAL 1 YEAR). You may have a new offer for 13 months for the price of 12, and setting the expiry lets you be flexible like that. It's even immune to the 29th Feb problem. In terms of reliability; if your batch process fails, running it a day late won't make you miss a bunch of people...
This query will simply check the Month and Day of every Join_Date against today, If you joined on Feb 29th, it will expire on Feb 28th or it will take 4 years to expire.
UPDATE Security_Table
SET Expired='TRUE'
WHERE Expired='FALSE'
AND
(
(DATE_FORMAT(Join_Date,'%m-%d')='02-29' AND DATE_FORMAT(NOW(),'%m-%d')='02-28')
OR
(DATE_FORMAT(Join_Date,'%m-%d') = DATE_FORMAT(NOW(),'%m-%d'))
);
You should also index the table so that only those records that have Expired='FALSE' are examined.
ALTER TABLE Security_Table ADD INDEX (Expired,Join_Date);
Give it a Try !!!
Related
So I'm setting up a query where I need to get items whose going to expire in a week before its expiration date(its expiration date is a month from its creation date)
I'm not really familiar with mysql's date and time functions so I'm not so sure of the syntaxes. Much appreciated ahead of time
EDIT: example, an item is created in feb 20th, its expiration date is march 20th. And lets say today is march 13th, my query needs to get the items whose expiration date is next week.
This is what I'm thinking what it may look like
SELECT * FROM ITEMS WHERE NOW() <= DATE_ADD(orders_items.cre_date, INTERVAL 1 MONTH) - 7 days?
you can do it the other way around (less complex)
get the items, whom were created 21 days -or more- ago
SELECT * FROM orders_items WHERE datediff(NOW() , orders_items.cre_date) >= 21
just to explain why 21? it's 3 weeks since create-date which leaves 7 days to expiration date.
you can read more about datediff
I want to delete all records in a database if the timestamp is older than 4 hours.
So my logic is to get the hour of the current time and get the hour of from the timestamp saved in the database and subtract to see if it is greater than 4. If it is greater than 4 than delete the records.
This is a code work in progress not really sure if it is correct.
DELETE FROM posts
WHERE id IN
(SELECT *
FROM posts
WHERE (HOUR(CURRENT_TIMESTAMP) - HOUR(time_published)) > 4)
)
if it makes a difference I am using MySQL.
Why not a simple
delete
from posts
where timestampdiff(hour, current_timestamp, time_published)>=4
Note that comparing the hour portions of date fields won't do what you expect. Consider comparing 21st Jan 1985 10:00 and 22nd Jan 1985 11:00. Your original condition would fail (1 hour), but it's actually 25 hours between them.
If you save the record at timestamp 1:00' and run this query at 5:59' nothing will be removed because the time difference is 4:59' and the hour component of that is 4! It might be what you want but that's way closer to 5 hours than 4.
Assuming that minutes are your smallest unit of precision, you might want to do something like
DELETE FROM posts
WHERE TIMESTAMPDIFF(MINUTE, CURRENT_TIMESTAMP, time_published) > 240
And use nested queries only when they are absolutely necessary; they possibly could slow your operations down drastically.
I have a table in Mysql which has column called 'dep_timestamp' which holds data in the following format (the data is received from a external source so can't be changed, and is displayed via web queries so can't be modified within that table)
2015-05-12 19:18:00 +0100
The database holds cancellations for booked taxi journeys which get pushed out to me from a central booking system in realtime. Throughout the day I will get any number of messages for cancelled journeys. A journey has a booked departure time dep_timestamp in its full format of 2015-05-12 19:18:00 +0100 that is used for reporting and all sort of other things.
Every day at 03:00 I want to delete all of the cancelled journeys that where due to depart 'yesterday' This means when my users do a query and ask what journeys have been cancelled today they only see stuff that has a booked departure of today.
I have an event setup on the server to delete rows older then 1 day using the following code;
DELETE FROM db.canx_today WHERE 'dep_timestamp' < DATE_SUB(CURRENT_TIME() , INTERVAL 1 DAY)
That event is set to run every day at 03:00 and does without error. However it takes the full date/time into consideration when running which means it only deletes the rows where the time & date are both older than one day.
If I swap CURRENT_TIME with CURRENT_DATE then the server throws this error; Truncated incorrect datetime value: '2015-05-13 10:17:00 +0100' which makes sense in so far that its looking for a full date/time string.
Is there a way to ignore the time element and just delete all rows that are from the previous day?
You can calculate based on CURRENT_DATE() and just concatenate 00:00:00 to that value.
WHERE `dep_timestamp` < CONCAT(CURRENT_DATE(), ' 00:00:00')
This should work, but will only be noticeably faster than the one I originally put in the comments above if dep_timestamp is indexed.
WHERE `dep_timestamp` < DATE_FORMAT(curdate(), "%Y-%m-%d 00:00:00")
Since DATE_FORMAT() actually returns a string, this might be more efficient when indexes are actually needed:
WHERE `dep_timestamp` < CAST(DATE_FORMAT(curdate(), "%Y-%m-%d 00:00:00") AS DATETIME)
DELETE FROM `canx_today`
WHERE DATE(`dep_timestamp`) = DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY);
I have an online calendar system that I use for tracking my band's gigs - I'd like to construct a query that will display all Fridays and Saturdays that don't currently have a record assigned to them.
eg,
if I have a record in the DB for Friday 23rd Aug and Friday 30th Aug (records being gigs that are booked), what would the query cirteria be to output Saturday 24th Aug (as it has no record)?
Select * from ['giglist']
where ['gigdate'is in 'friday','saturday']
and ['gigdate' doesn't have a record]
I will probably set the days of the week as variables so that the user can run the query for any day or selection of days.
Thanks,
Darren
if assuming from your question there is a field gigdate of date type that keeps date information and a seperate record field.
Then query would be,
select DAYNAME(gigdate), DAYOFMONTH(gigdate), MONTHNAME(gigdate) from giglist where
DAYNAME(gigdate) in ('Friday', 'Saturday') and
recordfield is NULL;
It's better to use single date type field and just store date only, as mysql has powerful set of date functions to help you out for your needs.
My db is made of groups of entries (by user) with a row for each day of the week and also groups where there is only 1 row per week of the year. This week may start Sat, Sun or Mon.
The sql groups all these rows by user id and works fine for the entries where the user has a row for every day
The problem I have is selecting the users rows where there is only one entry per week
Basically if the rows date is 11th Feb 2012 then I need to be able to select that row if the start date criteria falls on that date or within that following week and all rows upto but not including the row where the date column is after the end date
I'm trying everything like dateadd in the sql but I just cannot get it to add these rows in.
Hope I've made myself clear.
Say I have two entries in the db
2013-02-02
2013-02-09
I have a start date of 2013-02-05 and an end date of 2012-02-13
I need to get those two row as:
the start date falls on or within the week of 2013-02-02
and I also need 2013-02-09 as the end date falls on or within the week of that date.
Hope that makes it a bit clearer.
Not sure exactly what your question is asking.
If your field is of mysql date or datetime type, and you wanted to find if there was an entry for a given week could you not use MySQL WEEK Function to find all entries for the given week, you may also need to include a restriction on YEAR too.
You could also include the following week, but you may encounter problems. The main problem being week 52+1 of 2012 wont give week 1 of 2013, but week 1 of 2012.