MySql Date Query Incorrect result - mysql

When i run the below query, it returns all the results for dates falling within Date_add (CURDATE() AND CURDATE(), interval 30 day) but does not include results for Date_sub (CURDATE() AND CURDATE(), interval 15 day)
I know the data exists when I query with exact clause of deadline = '2015-01-15'
What could be wrong?
SELECT bug_id,
bug_status,
resolution,
short_desc,
deadline
FROM bugs
WHERE bug_status IN ( 'RESOLVED' )
AND deadline BETWEEN Curdate() AND Date_add(Curdate(), interval 30 day)
OR deadline BETWEEN Curdate() AND Date_sub(Curdate(), interval 15 day)

The rand for between is ordered. So, the second between is not correct. In addition, you probably want parentheses:
WHERE bug_status IN ( 'RESOLVED' ) AND
(deadline BETWEEN Curdate() AND Date_add(Curdate(), interval 30 day) OR
deadline BETWEEN Date_sub(Curdate(), interval 15 day) AND Curdate()
)
I mean, you might not want parentheses, so the query would then be:
WHERE (bug_status IN ( 'RESOLVED' ) AND
deadline BETWEEN Curdate() AND Date_add(Curdate(), interval 30 day)
) OR
deadline BETWEEN Date_sub(Curdate(), interval 15 day) AND Curdate()
In this case, the parentheses are redundant but they clarify the logic.

between's arguments should always be value BETWEEN low AND high. If you flip low and high, it'll return false. Moreover, you can unify both conditions to one:
deadline BETWEEN Date_sub(Curdate(), interval 15 day) AND
Date_add(Curdate(), interval 30 day)

Related

SQL turnover of the day before last year

I'm blocking on an SQL query. I am looking to recover the turnover of last year but the day before. For example: we are the 13/08/19 and I wish the turnover of yesterday of last year so 12/08/18.
How can I do that? Here is my request:
SELECT SUM(total_paid/1.2)
FROM '._DB_PREFIX_.'orders
WHERE o.date_add BETWEEN DATE_FORMAT(
CASE
WHEN YEAR( DATE_SUB( now(), INTERVAL 364 DAY ) ) = YEAR(now() )
THEN DATE_SUB(concat(YEAR(now()),'-',MONTH(now()),'-01'), INTERVAL 371 DAY)
ELSE DATE_SUB(concat(YEAR(now()),'-',MONTH(now()),'-01'), INTERVAL 364 DAY) END, '%Y/%m/%d') AND
CASE
WHEN YEAR( DATE_SUB( now(), INTERVAL 364 DAY ) ) = YEAR(now() )
THEN DATE_SUB(now(), INTERVAL 371 DAY)
ELSE DATE_SUB(now(), INTERVAL 364 DAY) END
AND valid=1
table
Thanks for help.
It seems you should be able to simplify your query to something like this:
SELECT SUM(total_paid/1.2)
FROM '._DB_PREFIX_.'orders
WHERE DATE(o.date_add) = CURDATE() - INTERVAL 1 YEAR - INTERVAL 1 DAY
Note that dependent on how you want to treat February 29, you may want to change the expression to
CURDATE() - INTERVAL 1 DAY - INTERVAL 1 YEAR
In the first form, 2020-02-29 will map to 2019-02-27, in the second it will map to 2019-02-28.
{
select sum(your_total_column/1.2) from your_tab
where now() =(CASE WHEN mod(year(your_date_column),4) = 0
THEN DATE_ADD(your_date_column,INTERVAL 367 DAY)
ELSE DATE_ADD(your_date_column,INTERVAL 366 DAY));}
The idea is find if your_date_column is leap year if it is leap year then add 367 else add 366 and compare with current date.

mysql use a different set of WHERE statements if this=1

I need to do a single select on a table, but if Product='football' I need to do a couple of WHEREs, but if Product='something' then do something else. I am not sure if I need to do an IF statement, or a UNION or a CASE which I have never used.
Example of what I would like to have worked but obviously doesn't
SELECT *
FROM
orders
IF Product = 'Football'{
WHERE
AND RenewalDate < DATE_ADD(CURDATE(), INTERVAL 31 DAY)
AND RenewalDate > DATE_SUB(CURDATE(), INTERVAL 31 DAY)
}ELSE IF Product = 'Something'{
AND RenewalDate < DATE_ADD(CURDATE(), INTERVAL 10 DAY)
AND RenewalDate > DATE_SUB(CURDATE(), INTERVAL 10 DAY)
}
ORDER BY
RenewalDate
Now I know that looks like php but its just to show roughly what I want to happen
No if required. Just boolean logic:
SELECT o.*
FROM orders o
WHERE (Product = 'Football' AND
RenewalDate < DATE_ADD(CURDATE(), INTERVAL 31 DAY)
RenewalDate > DATE_SUB(CURDATE(), INTERVAL 31 DAY)
) OR
(Product = 'Something' AND
RenewalDate < DATE_ADD(CURDATE(), INTERVAL 10 DAY) AND
RenewalDate > DATE_SUB(CURDATE(), INTERVAL 10 DAY)
)
ORDER BY RenewalDate;

Confusion about using a where clause, date interval, and 'and' and or 'or', should be quick

SELECT *
FROM romantic_dates
WHERE
asker = 'lover' AND date_start BETWEEN NOW() + INTERVAL 90 DAY AND NOW() - INTERVAL 31 DAY
OR
giver = 'lover' AND date_start BETWEEN NOW() + INTERVAL 90 DAY AND NOW() - INTERVAL 31 DAY
ORDER BY date_start DESC;
This is a where clause I am building. I am confused on just how to use the 'or' and between now() and interval. Anyone available to help? This question is slightly different then the others I searched for in that there are docs on one or the other on and off stackoverflow, but not dealing with both.
The operands for between are ordered, so the first needs to be less than the second. That is not the case with your expression. So:
SELECT rd.*
FROM romantic_dates rd
WHERE (asker = 'lover' AND date_start BETWEEN NOW() - INTERVAL 31 DAY AND NOW() + INTERVAL 90 DAY) OR
(giver = 'lover' AND date_start BETWEEN NOW() - INTERVAL 31 DAY AND NOW() + INTERVAL 90 DAY)
ORDER BY date_start DESC;
I would be inclined to factor out the date expression and use:
SELECT rd.*
FROM romantic_dates rd
WHERE date_start BETWEEN NOW() - INTERVAL 31 DAY AND NOW() + INTERVAL 90 DAY AND
'lover' in (asker, giver)
ORDER BY date_start DESC;

MySQL: Select all fields while defining a variable?

Very simple concept. I am selecting specific rows based on the date they where generated (X days ago) and organizing them by the time frame (in this case, the variable is OVERDUEDAYS). The only problem I am having now is defining OVERDUEDAYS and also selecting the entire rows content without having to define each column in the select statement.
Without further ado (this is what I am hoping to achieve):
SELECT DATEDIFF(CURDATE(), DATE(date_generated)) AS OVERDUEDAYS, * FROM invoices WHERE
(DATE(date_generated) = DATE_SUB(CURDATE(), INTERVAL 10 DAY)
OR
DATE(date_generated) = DATE_SUB(CURDATE(), INTERVAL 30 DAY)
OR
DATE(date_generated) = DATE_SUB(CURDATE(), INTERVAL 45 DAY)
OR
DATE(date_generated) = DATE_SUB(CURDATE(), INTERVAL 53 DAY)
OR
DATE(date_generated) = DATE_SUB(CURDATE(), INTERVAL 60 DAY))
AND
(paid=0 AND cancelled=0)
The query works great when you remove the wildcard and define each column manually... But that is a lot of columns and I would like to avoid that at all costs. Suggestions?
SELECT * FROM invoices WHERE colunm_id IN (
SELECT colunm_id FROM invoices WHERE
(DATE(date_generated) = DATE_SUB(CURDATE(), INTERVAL 10 DAY)
OR
DATE(date_generated) = DATE_SUB(CURDATE(), INTERVAL 30 DAY)
OR
DATE(date_generated) = DATE_SUB(CURDATE(), INTERVAL 45 DAY)
OR
DATE(date_generated) = DATE_SUB(CURDATE(), INTERVAL 53 DAY)
OR
DATE(date_generated) = DATE_SUB(CURDATE(), INTERVAL 60 DAY))
AND
(paid=0 AND cancelled=0)
)

select all records created within the hour

startTimestamp < date_sub(curdate(), interval 1 hour)
Will the (sub)query above return all records created within the hour? If not will someone please show me a correct one? The complete query may look as follows:
select * from table where startTimestamp < date_sub(curdate(), interval 1 hour);
Rather than CURDATE(), use NOW() and use >= rather than < since you want timestamps to be greater than the timestamp from one hour ago. CURDATE() returns only the date portion, where NOW() returns both date and time.
startTimestamp >= date_sub(NOW(), interval 1 hour)
For example, in my timezone it is 12:28
SELECT NOW(), date_sub(NOW(), interval 1 hour);
2011-09-13 12:28:53 2011-09-13 11:28:53
All together, what you need is:
select * from table where startTimestamp >= date_sub(NOW(), interval 1 hour);