Any date 1 year from between selected dates MYSQL query - mysql

I am building a report for people who signed up 1 year ago.
I want to run this report at a given time. So anyone that has been a member for 1 year between two dates.
It's a form with between date1 and date2 with a submit.
So if i want to see anyone who has been a member between 01-08-2014 and 01-10-2014 as an example. Anyone that would have been or was a member between those dates show in a list.
So far i have this but its not displaying any records:
SELECT *
FROM `nfw_users`
WHERE DATE(date_join) BETWEEN 2012-05-20
AND 2012-10-20 AND date_join >= DATE_SUB(NOW(),INTERVAL 1 YEAR)

Likely the literals 2012-05-20 and 2012-10-20 in your query are evaluating to NULL in a "date" context. (That's valid syntax, but likely not what you want.)
Date literals should be enclosed in single quotes, e.g.
... BETWEEN '2012-05-20' AND '2012-10-20'
^ ^ ^ ^
As of right now ('2014-10-14 06:36:36'), this predicate:
date_join >= DATE_SUB(NOW(),INTERVAL 1 YEAR)
is equivalent to:
date_join >= '2013-10-14 06:36:36'
That means that no rows with date_join less than that value will be returned, so no rows can be returned, since there are no date_join values that are greater than '2013-10-14' that are also less than or equal to '2012-10-20'. The predicates in your query make it impossible for any rows to match.
Your specification is a little ambiguous. Some example data, and which rows you expect to be returned would go a long ways towards clarifying the specification. You want to return rows for individuals who were members for exactly one year, or at least one year, within a given date range?
To return rows for "members" who hit a one year anniversary sometime between two specific dates:
WHERE date_join >= '2013-05-20' + INTERVAL -1 YEAR
AND date_join < '2013-10-20' + INTERVAL 1 DAY + INTERVAL -1 YEAR
To return rows for "members" who have been (or would have been) members for at least a full year between two dates, I don't see that two boundaries would be required for that, a check against a single lower bound date would be sufficient.

Try below query and you are missing quotes around date like "2012-05-20"
SELECT *
FROM `nfw_users`
WHERE DATE(date_join) BETWEEN "2013-05-20" AND "2013-10-20"
AND YEAR(date_join) = YEAR(NOW() - INTERVAL 1 YEAR)

Related

What's the difference between the two SQL statements?

This is a question from leetcode, using the second query I got the question wrong but could not identify why
SELECT
user_id,
max(time_stamp) as "last_stamp"
from
logins
where
year(time_stamp) = '2020'
group by
user_id
and
select
user_id,
max(time_stamp) as "last_stamp"
from
logins
where
time_stamp between '2020-01-01' and '2020-12-31'
group by
user_id
The first query uses a function on every row to extract the year (an integer) and compares that to a string. (It would be preferable to use an integer instead.) Whilst this may be sub-optimal, this query would accurately locate all rows that fall into the year 2020.
The second query could fail to locate all rows that fall into 2020. Here it is important to remember that days have a 24 hour duration, and that each day starts at midnight and concludes at midnight 24 hours later. That is; a day does have a start point (midnight) and an end-point (midnight+24 hours).
However a single date used in SQL code cannot be both the start-point and the end-point of the same day, so every date in SQL represents only the start-point. Also note here, that between does NOT magically change the second given date into "the end of that day" - it simply cannot (and does not) do that.
So, when you use time_stamp between '2020-01-01' and '2020-12-31' you need to think of it as meaning "from the start of 2020-01-01 up to and including the start of 2020-12-31". Hence, this excludes the 24 hours duration of 2020-12-31.
The safest way to deal with this is to NOT use between at all, instead write just a few characters more code which will be accurate regardless of the time precision used by any date/datetime/timestamp column:
where
time_stamp >= '2020-01-01' and time_stamp <'2021-01-01'
with the second date being "the start-point of the next day"
See answer to SQL "between" not inclusive

Return rows for next month, MYSQL

I have a mysql table which stores users' availability, stored in 'start' and 'end' columns as date fields.
I have a form where other users can search through the 'availabilty' with various periods like, today, tomorrow and next week . I'm trying to figure out how to construct the query to get all the rows for users who are available 'next month'.
The 'start' values maybe from today and the 'end' value might might be three months away but if next month falls between 'start' and 'end' then I would want that row returned.
The nearest I can get is with the query below but that just returns rows where 'start' falls within next month. Many thanks,
sql= "SELECT * FROM mytable WHERE start BETWEEN DATE_SUB(LAST_DAY(DATE_ADD(NOW(), INTERVAL 1 MONTH)),INTERVAL DAY(LAST_DAY(DATE_ADD(NOW(), INTERVAL 1 MONTH)))-1 DAY) AND LAST_DAY(DATE_ADD(NOW(), INTERVAL 1 MONTH))";
As you are interested in anything that happens in the full month following the current date you could try something like this:
SELECT * FROM mytable WHERE
FLOOR(start/100000000)<=FLOOR(NOW()/100000000)+1 AND
FLOOR( end/100000000)>=FLOOR(NOW()/100000000)+1
This query make use of the fact that datetime values are stored in MySql internally as a number like
SELECT now()+0
--> 20150906130640
where the digits 09 refer to the current month. FLOOR(NOW()/100000000) filters out the first digits of the number (in this case:201509). The WHERE conditions now simply test whether the start date is anywhere before the end of the next month and the end date is at least in or after the period of the next month.
(In my version I purposely left out the condition that start needs to be "after today", since a period that has started earlier seems in my eyes still applicable for your described purpose. If, however, you wanted that condition included too you could simply add an AND start > now() at the end of your WHERE clause.)
Edit
As your SQLfiddle is set-up with a date instead of a (as I was assuming) datetime column your dates will be represented differently in mumeric format like 20150907 and a simple division by 100 will now get you the desired month-number for comparison (201509):
SELECT * FROM mytable WHERE
FLOOR(start/100)<=FLOOR(NOW()/100000000)+1 AND
FLOOR( end/100)>=FLOOR(NOW()/100000000)+1
The number returned by NOW() is still a 14-digit figure and needs to be divided by 100000000. See your updated fiddle here: SQLfiddle
I also added another record ('Charlie') which does not fulfill your requirements.
Update
To better accommodate change-of-year scenarios I updated my SqlFiddle. The where clause is now based on 12*YEAR(..)+MONTH(..) type functions.

Select leave data from attendance table given the following condition

I have attendance data for employees stored in the table attendance with the following column names:
emp_id (employee ID)
date
type (leave, absent, etc.)
(there are others but I'm omitting them for the sake of simplicity)
My objective is to retrieve all dates of the given month on which the employee was on leave (type = 'Leave') and the last leave taken in the last month, if any.
It's easy to do it using two queries (I'm using PHP to get process the data), but is there any way this can be done in a single query?
I'm answering my own question so as to close it. As #bpgergo pointed out in the comments, UNION will do the trick here.
SELECT * FROM table_name
WHERE type="Leave" AND
date <= (CURRENT_DATE() - 30)
Select the fields, etc you want then se a combined where clause using mysql's CURRENT_DATE() function. I subtracted 30 for 30 days in a month.
If date is a date column, this will return everyone who left 1 month or longer ago.
Edit:
If you want a specific date, change the 2nd month like this:
date <= (date_number - 30)

Gather individual record for the last three days

I have a table that contains three things: a start number, an end number, and a date which look something like this:
table: number2day
first last day
109288787 136388928 2013-06-29
136388929 144276079 2013-06-30
144276080 147295660 2013-07-01
Given today's date, I need to find the first value from days ago so I can compare it to a number within another query
I know that there is WHERE <col-name> IN (SUBQUERY) syntax but there is a similar statement that can use operators? >,<,=?
Something like:
WHERE num >= (SELECT first FROM number2day WHERE day = SUBDATE(CURDATE(), 3))
Here I only want to check if num is greater than first from 3 days ago. Any thoughts?
The ALL keyword should work for you here:
WHERE NUM >= ALL (SELECT first FROM number2day WHERE day = SUBDATE(CURDATE(), 3))

How to get the greatest of two columns values in MySQL?

I'm trying to do something like this:
SELECT MAX(
ADDDATE(expirationdate, INTERVAL 1 YEAR),
ADDDATE(now(), INTERVAL 1 YEAR)
)
That is, get "a year from now", or "a year from the expiration date stored in the table", whichever is greater (i'm renewing people's subscriptions).
This obviously doesn't work, since MAX() is for aggregation between rows, not for comparing 2 values. Is there a function that'll do this in MySQL? (i'd like to avoid doing an IF)
greatest()