MySQL Query how to show opposite results - mysql

im using this SQL Query in my PHP code:
SELECT
*
FROM
maintenance
WHERE
from_date <= DATE_ADD(NOW(), INTERVAL 5 DAY)
AND to_date >= DATE(NOW())
ORDER BY
from_date ASC
its showing rows 5 days before the from_date field. so basically rows where the maintenance is still pending as the date hasn't passed yet.
i want to be able show the oposite results. so all the rows where the maintenance is completed if possible?

You can exclude these results:
SELECT
*
FROM
maintenance
WHERE id NOT IN (SELECT
id
FROM
maintenance
WHERE
from_date <= DATE_ADD(NOW(), INTERVAL 5 DAY)
AND to_date >= DATE(NOW())
)
ORDER BY
from_date ASC
Or simply, negate the condition in your original query.

Related

How to get rows from MySQL table with two field to order by?

I have a table in MySQL with fields:
id - int;
date - datetime;
rating - decimal(3,2);
and so on, other fields are not necessary in this selection.
There are about 6000 rows in the table.
I have to get rows from the table that is ordered by rating ASC for the last 6 months and then other rows ordered by id ASC.
How can I do it?Will it work fast?
I would do something like this to achieve that:
select *
from tbl
order by case
when date >= DATE_ADD(curdate(), INTERVAL -6 MONTH) then
rating
else id
end ASC;
You need to make sure that all the records from the last 6 months come first in the result, and then worry about ordering by rating or id. You can do that by ordering on the boolean
date >= CURDATE() - INTERVAL 6 MONTH
first, and then on either rating or id as appropriate. For example:
SELECT *
FROM data
ORDER BY date >= CURDATE() - INTERVAL 6 MONTH DESC,
CASE WHEN date >= CURDATE() - INTERVAL 6 MONTH THEN rating
ELSE id
END

SQL date not relative

I have a table in which i store every 15 minutes result of a cron job, which is nothing more than a timestamp, a population number and an id.
I am trying to query it as following.
SELECT ROUND(AVG(`population`),0) AS population, DATE(`time`) AS date
FROM `swg_servertracker`
WHERE `time` >= DATE(NOW()) - INTERVAL 7 DAY
GROUP BY DATE(`time`)
DESC
LIMIT 7
What it does it creates an daily average, and grabs the last 7 entries. Sadly in was not in the right order, so i flipped it to ascending. My problem is when i inverse (asc) it, it skips today, and goes back an extra day (today is the 3rd of october, which is not taken in the equation when i use the ascending)
I tried to set the where statement to just now - interval 168 hours (which is also 7 days but then relative back) which had no result either on this. Still it skips today and just goes back 7 days from on yesterday.
SELECT ROUND(AVG(`population`),0) AS population, DATE(`time`) AS date
FROM `swg_servertracker`
WHERE `time` >= NOW() - INTERVAL 168 HOUR
GROUP BY DATE(`time`)
ASC
LIMIT 7
So is there a way I can take today in account as well?
You select 8 records instead 7 records. If you want to select 7 latest records, you must use "greater than" sign instead "greater than or equal" sign.
SELECT ROUND(AVG(`population`),0) AS population, DATE(`time`) AS date
FROM `swg_servertracker`
WHERE `time` > NOW() - INTERVAL 7 DAY
GROUP BY DATE(`time`)
ASC
LIMIT 7
You can get the result-set in a Derived table, and do a sorting on the results again.
Note that, in MySQL, Aliases defined in the Select clause can be used in Group By, Having and Order By clauses. So, I have aliased DATE(time) to avoid re-computation in Group by and Order By.
You can do this instead:
SELECT dt.population,
dt.date1 AS date
FROM (
SELECT ROUND(AVG(`population`),0) AS population,
DATE(`time`) AS date1
FROM `swg_servertracker`
WHERE `time` >= DATE(NOW()) - INTERVAL 7 DAY
GROUP BY date1
ORDER BY date1 DESC
LIMIT 7
) AS dt
ORDER BY dt.date1 ASC

How can I add days to a date in MYSQL in a query

I am trying to add 5 days to a date in MYSQL in a query. This is what I have done:
SELECT * FROM sales INNER JOIN partner on user_id = idpartner WHERE DATE((end_date) + 5) >= DATE(NOW()) ORDER BY end_date ASC LIMIT 0,50000
But this is not showing the list of sales which has ended. Can someone please tell me where I am making a mistake.
It looks like you want rows where end_date is later than five days ago.
The best way to get that is with
WHERE end_date >= CURDATE() - INTERVAL 5 DAY
The business of adding integers to dates doesn't work in MySQL (it's an Oracle thing). So you need to use the INTERVAL n unit syntax.
You'll notice that my WHERE clause above is functionally equivalent to
WHERE DATE(end_date) + INTERVAL 5 DAY >= DATE(NOW())
But, the first formulation is superior to the second for two reasons.
if you mention end_date in a WHERE clause without wrapping it in computations, your query can exploit an index on that column and can run faster.
DATE(NOW()) and CURDATE() both refer to the first moment of today (midnight). But CURDATE() is a bit simpler.
To fix the original query, you can use DATE_ADD with the INTERVAL keyword:
SELECT
*
FROM
sales
INNER JOIN
partner ON user_id = idpartner
WHERE
DATE_ADD(end_date, INTERVAL 5 DAY) >= DATE(NOW())
ORDER BY end_date ASC
LIMIT 0 , 50000
Said that, I wouldn't recommend applying functions such as DATE_ADD on columns, as it means that the database won't be able to use an index on end_date. Therefore, I would modify the query to:
SELECT
*
FROM
sales
INNER JOIN
partner ON user_id = idpartner
WHERE
end_date <= DATE_ADD(DATE(NOW()), INTERVAL 5 DAY)
ORDER BY end_date ASC
LIMIT 0 , 50000
As you can see, in the second alternative all functions are applied on constants and not on columns (end_date).
You can try
DATE_ADD() here is the
Link
Select DATE_ADD(DATE_FORMAT(NOW(),'%Y-%m-%d'),INTERVAL 1 DAY) FROM DUAL

Count of records for the last and current month unix timestamp

I need to make statistics page for billing with auto query. For example now is july and query must show count of record for the june and current count of records on current day(only july). Sort of:
"records for the last month - 85, for the current day - 32"
I have table customer and row create_time but it is in unix timestamp. Tried
SELECT COUNT(*) FROM customer WHERE create_time >=
UNIX_TIMESTAMP(DATE_SUB(now(), INTERVAL 1 MONTH))
but its absolutely not what i want.
I would appreciate for any help.
Try this:
SELECT *
FROM ( SELECT COUNT(*) AS total_previous_month
FROM customer
WHERE create_time >= concat(date_format(LAST_DAY(now() - interval 1 month),'%Y-%m-'),'01')
AND create_time < LAST_DAY(now() - interval 1 month )
) AS s1,
( SELECT COUNT(*) AS total_previous_month
FROM customer
WHERE create_time >= concat(extract(year from now()),'-',extract(month from now()),'-01')
AND create_time <= now()
) AS s2
You can do this by adding condition to the WHERE:
create_time >= UNIX_TIMESTAMP(DATE_SUB(CURDATE(), INTERVAL 1 month))
in PHP you can calculate the one month back date
$newDate = strtotime('-1 month');
and use this in query

Display rows from MySQL where a datetime is within the next hour

I always have trouble with complicated SQL queries.
This is what I have
$query = '
SELECT id,
name,
info,
date_time
FROM acms_events
WHERE date_time = DATE_SUB(NOW(), INTERVAL 1 HOUR)
AND active = 1
ORDER BY date_time ASC
LIMIT 6
';
I want to get up to 6 rows that are upcoming within the hour. Is my query wrong? It does not seem to get events that are upcoming within the next hour when I test it.
What is the correct syntax for this?
I'm going to postulate that you're looking at a group of records that contain a range of DATETIME values, so you probably want something more like this:
SELECT id,
name,
info,
date_time
FROM acms_events
WHERE date_time < DATE_ADD(NOW(), INTERVAL 1 HOUR)
AND date_time >= NOW()
AND active = 1
ORDER BY date_time ASC
LIMIT 6
Otherwise, your query is looking for records with a date_time of exactly "now + 1 hour". I'm assuming all your dates aren't specific to that particular second. ;)
To clarify a bit, DATE_ADD() and DATE_SUB() return exact timestamps, so your query above roughly translates to something like SELECT ... WHERE date_time = '2010-04-14 23:10:05' ORDER BY ..., which I don't think is what you want.
WHERE date_time = DATE_SUB(NOW(), INTERVAL 1 HOUR)
means date_time equals exactly now minus one hour, which would result in any record exactly one hour old.
Why not use
WHERE TIMEDIFF(date_time, NOW()) < '01:00:00'
AND date_time > NOW()