how to the min and the max date in sql - mysql

Hi i want to substruct to fields between the min and the max date heres my query:
SELECT Max(km) - MIN(km)
from positions
where deviceid = 2
and cast(devicetime as date) between MIN('2017-03-23') and Max('2017-03-23'))
but it gives an error.
PS, devicetime in the database is a datetime type, i'm using mysql
the error is:invalide group function

You do not need MIN and MAX in between:
SELECT Max(km) - MIN(km)
from positions
where deviceid = 2
and cast(devicetime as date) between '2017-03-23 00:00:00' and '2017-03-23 23:59:59'

Try this instead:
SELECT Max(km) - MIN(km)
from positions
where deviceid = 2
and cast(devicetime as date) between '2017-03-23' and '2017-03-23'
You can't use aggregation functions in the where clause, only in select, having or order by clause.

Remove min & max from where....that is not allowed. Try the below sql. Added timestamp so you get the accurate result.
SELECT Max(km) - MIN(km)
from positions
where deviceid = 2
and cast(devicetime as date) between '2017-03-23 00:00:00' and '2017-03-23 23:59:59'

In SQL Server you can use below code,
SELECT Max(km) - MIN(km) KiloMeter FROM positions
where deviceid = 2
Group by deviceid,devicetime
Having cast(devicetime as datetime) between MIN('2017-03-21') and Max('2017-03-26')
Please look in to aggregate and non-aggregate functions..
Thank you..

Your specific problem are the aggregation functions in the WHERE clause. However, you should also note that when using columns in the WHERE, it is a bad idea to use functions or type casting. That prevents the use of indexes.
So, a better version uses inequalities:
select min(km) - max(km)
from positions
where deviceid = 2 and
devicetime >= '2017-03-23' and
devicetime < '2017-03-24';
If performance is an issue, you want an index on positions(deviceid, devicetime, km).

Related

How to sort by date in mysql

I need to perform the following query in mysql.
SELECT
evaluationpart.id,
evaluationpart.creation,
evaluationpart.evaluationid,
evaluationpart.partid,
evaluation.horimeter,
personcompressorpart.hourcapacity,
evaluation.evaluationdate AS changedate,
evaluation.averageworkload,
#ed := DATEDIFF(curdate(), evaluation.evaluationdate) AS elapseddays,
#uh:= #ed * evaluation.averageworkload AS usedhours,
#htu:= personcompressorpart.hourcapacity - #uh AS hourstouse,
#nc:= curdate() + INTERVAL (#htu/evaluation.averageworkload) DAY AS nextchange
FROM evaluationpart
LEFT JOIN evaluation ON evaluation.id = evaluationpart.evaluationid
LEFT JOIN personcompressorpart ON personcompressorpart.id = evaluationpart.partid
ORDER BY #nc ASC
But the Order By is not working and I'm getting this result
Could anyone tell me why?
It seems that you are not using the column name in the ORDER BY clause.
If you want to order the query result by the column named 'nextchange', the ORDER BY clause should be ORDER BY nextchange ASC.
Here's the MySQL documentation on Sorting Rows: https://dev.mysql.com/doc/refman/8.0/en/sorting-rows.html
I hope this helps.

running into "unknown tablefield" but it is defined

running a query and converting the stored unix-time-stamp to the certain date-format. this i wanna compare with the timestamp of today...
i am running within the where condition into the error that "D" is not known?
SELECT
COUNT(distinct db_suid),
date_format(from_unixtime(d_utime),'%H') AS H,
date_format(from_unixtime(d_utime),'%Y-%m-%d') AS D
FROM air_vault
WHERE CURRENT_DATE = D
GROUP BY H
at the end i wanna get the distinct number of values per hour of today
You can't use alias defined in select also in where clause
SELECT
COUNT(distinct db_suid),
date_format(from_unixtime(d_utime),'%H') AS H,
date_format(from_unixtime(d_utime),'%Y-%m-%d') AS D
FROM air_vault
WHERE CURRENT_DATE = date_format(from_unixtime(d_utime),'%Y-%m-%d')
GROUP BY H
I would suggest doing:
SELECT COUNT(distinct db_suid),
date_format(from_unixtime(d_utime),'%H') AS H,
date_format(from_unixtime(d_utime),'%Y-%m-%d') AS D
FROM air_vault av
WHERE d_utime >= unix_timestamp(curdate()) and
d_utime < unix_timetamp(curdate() + interval 1 day)
GROUP BY H, D;
Why is the logic phrased this way? The conditions in the where clause can use an index on d_utime if it is available -- or partitions if the data is partitioned on that column. That can significantly increase the performance of the query.
When a column is the argument to a function (such as from_unixtime()), indexes are almost never used.
manged my issue by modifying my WHERE condition:
WHERE CURRENT_DATE = date_format(from_unixtime(d_utime),'%Y-%m-%d')

SQL - Select all rows which is >= and <=

i trying to do a sql query which i combine de compare operators with substring.
in my column date i have the following value inside : 09-01-2014 12:02:55
what i try to now is to select all rows which is >= 09-01-2014 and for example <=22-01-2014
how can i do it?
i have trying for example with this code:
SELECT * From table Where Name= 'Something'
AND SUBSTRING(date,1,10) = '09-01-2014'
AND SUBSTRING(date,1,10) < '22-01-2014'
You can use the BETWEEN operator
SELECT * FROM table
WHERE Name = 'Something'
AND SUBSTRING(date, 1, 10) BETWEEN '09-01-2014' AND '22-01-2014'
EDIT: I'm still leaving this here, but it is not an error proof solution (as pointed out by oerkelens down in the comments)
The BETWEEN operator will work, like this:
SELECT *
From table
Where Name= 'Something'
AND `date` BETWEEN '2014-01-09' AND '2014-01-23'
Working Demo: http://sqlfiddle.com/#!2/b4d7e
Try this:
SELECT *
FROM tableA a
WHERE a.nme= 'Something' AND
DATE(STR_TO_DATE(a.date, '%d-%m-%Y %H:%i:%s')) >= '2014-01-09' AND
DATE(STR_TO_DATE(a.date, '%d-%m-%Y %H:%i:%s')) <= '2014-01-22';
OR
SELECT *
FROM tableA a
WHERE a.nme= 'Something' AND
DATE(STR_TO_DATE(a.date, '%d-%m-%Y %H:%i:%s')) BETWEEN '2014-01-09' AND '2014-01-22';
Using the following syntax makes your query sargable. It allows query to use any Indexes defined on the date column. for more information SARGable Queries with Datetime Datatype
SELECT * From table
Where Name= 'Something'
AND [DateColumn] >= '20140109'
AND [DateColumn] <= '20140122'
You are converting the date from the table row into a string before comparing to the bookend dates. You need to do the opposite. Convert the bookend dates from strings to dates, then compare each test date.
Some form of the CONVERT or CAST function should do that for you.
The reason your approach won't work is that when SQL server compares strings, it uses alphabetical order. You want ascending date order, which is a different order.
Which Database do you use? Oracle:
SELECT *
FROM table tbl
WHERE 1=1
AND name = 'Something'
AND trim(tbl.column) >= to_date('2014-01-09','DD-MM-YYYY')
AND trim(tbl.column) <= to_date('2014-01-22','DD-MM-YYYY')
or you just convert it into a number/integer like YYYYMMDD then the >= =< operators will work too.

mysql using a DateTime in the whereclause

I tried this query below but it still returns days that had -1 values. I want the where clause to return rows that are 2 days or newer. Thanks!
SELECT uniqueKey,(TO_DAYS(TimeStampColumn) - TO_Days(Now())) as 'dayDiff'
FROM couponextractor.tblresults
where 'dayDiff' >= 0
Because you just compare string 'daydiff' >= 0, which always evaluates to 0 => true
You need to get rid of quotes and use HAVING, beside that's very inefficient query... it's better to compute the date before and just use >= operator on the column.
HAVING dayDiff >= 0
So just compute the exact date, and then just do
WHERE TimeStampColumn >= "XXXX-XX-XX AA:AA:AA" so it can be optimized by the server if you have indexes.
SELECT * FROM tbl WHERE datetime < NOW() - INTERVAL 2 DAY
Why don't you use the MYSQL DATEDIFF- Function?
SELECT uniqueKey,DATEDIFF(TimeStampColumn,Now()) as 'dayDiff'
FROM couponextractor.tblresults
where DATEDIFF(TimeStampColumn,Now()) >= 1
Think this will do the job. Perhaps you have to cast the TimeStampColumn.

Select by Month of a field

How can I get records from my table using month/year? I have a table like this:
Name - varchar
DueDate -datetime
Status -boll
DueDate is project due date, I want record corresponding to month/year, not full date, I mean record for specific month.
How can I do this in mysql?
Simply use MONTH() and YEAR():
SELECT * FROM Project WHERE MONTH(DueDate) = 1 AND YEAR(DueDate) = 2010
You could use a between statement:
select * from Project
where DueDate between '2010-01-01' and '2010-02-01'
Do not use this here recommended solution with MONTH() and YEAR(). It prevents MySQL to use index on column DueDate if you have one and it forces MySQL to examine all rows in table.
Instead, use BETWEEN clause like this:
SELECT * FROM Project
WHERE DueDate BETWEEN '2010-01-01' AND '2010-02-01'
Or another solution with IN clause:
SELECT * FROM Project
WHERE DueDate IN ('2010-01-01', '2010-01-02', '2010-01-03', ..., '2010-01-31')
This two solutions allows MySQL to use index, so performance will be better.
SELECT Name FROM Table Where MONTH(datetime) = 1;
1 = January.
http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_month
it will select current year's specific month
SELECT * FROM Project WHERE MONTH(DueDate) = 1 AND YEAR(DueDate) = YEAR(NOW())
If you input month format "Y-m" you can use:
SELECT * FROM Project WHERE DATE_FORMAT(DueDate,"%Y-%m") = '2010-01'
You can extract the MONTH() and YEAR() for your DueDate.
SELECT * WHERE MONTH(DueDate) = '5' AND YEAR(DueDate) = '1987';
SELECT * FROM TABLE WHERE DueDate LIKE '2020-01%';
use in case you can substring your date data.