I want to group the records by every 15 minutes based on the time stamp column using the below query, but the first two record difference in only 10 min.
RAILS CODE:
select("DATE_FORMAT(reading_on,'%H:%i') as date,
ROUND(UNIX_TIMESTAMP(reading_on)/(900)) as fif ,
max(power) as total").group("fif").where("imei= #{site}" ).order("fif asc")
MYSQL QUERY:
SELECT DATE_FORMAT(reading_on,'%H:%i') as date,
ROUND(UNIX_TIMESTAMP(reading_on)/(900)) as fif ,
max(power) as total FROM `clarodetails`
WHERE (imei= 353469040778516)
AND (date(reading_on) between '2012-11-18 00:00:00'
AND '2012-11-18 23:59:59')
GROUP BY fif
ORDER BY fif asc LIMIT 15
OUTPUT:
You could use this:
SELECT
DATE_FORMAT(
FROM_UNIXTIME(UNIX_TIMESTAMP(reading_on) -
MOD(UNIX_TIMESTAMP(reading_on), 900)), '%H:%i') as fif,
max(power) as total
FROM `clarodetails`
WHERE
(imei= 353469040778516)
AND (date(reading_on) >= '2012-11-18')
AND (date(reading_on) < '2012-11-19')
GROUP BY fif
ORDER BY fif asc LIMIT 15
i also prefer not to use between '2012-11-18 00:00:00' and '2012-11-18 23:59:59' (you could always miss some records with reading_on after 23:59:59 but before midnight...)
This is probably due to the mixing of aggregate and non-aggregate functions. The first result column is not aggregated, so the result set shows the first value of this column which the query encounters. Include the date column in the aggregation:
...GROUP BY fif, date...
Related
I'm trying to make a chart where the X axis is the date (last 14 days) and the chart itself shows the count of the post on that date. However, it starts with 1. oct -> 9. oct and then proceeds with 25. sep -> 30.sep
My SQL:
SELECT DATE_FORMAT(created_at, "%d. %b") AS date, count(*) as count
FROM posts
WHERE created_at BETWEEN NOW() - INTERVAL 14 DAY AND NOW()
Group by date
ORDER BY date ASC
Image of the issue: https://i.imgur.com/d8AIRu6.png
The problem is that date in the order by clause references the alias defined in the select clause, that is a string representation of the date. You can't use that to sort the resultset as you want.
Here is one workaround: add another expression to the group by clause that has a date datatype - you can then use it to order the results:
SELECT date_format(created_at, '%d. %b') AS date, count(*) as count
FROM posts
WHERE created_at BETWEEN NOW() - INTERVAL 14 DAY AND NOW()
Group by date, date(created_at)
ORDER BY date(created_at) ASC
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
Imagine a table with field 'datetime'. Example rows:
2017-01-27 13:06:02
2017-01-27 05:13:14
2017-01-23 22:13:56
2017-01-26 14:02:09
2017-01-23 13:26:12
...
I need to get * from the bold lines, BUT WITHIN the last 30 days from now...
In other words, rows with the max date in the last 30 days.
30 rows in total in each case, assuming every day has at least one row...
You can group by the date part of datetime and get the max for each day.
select max(`datetime`)
from tablename
where `datetime` >= date(now())-interval '30' day
group by date(`datetime`)
To get all the fields from the table for such rows, use
select * from tablename where `datetime` in (
select max(`datetime`)
from tablename
where `datetime` >= date(now())-interval '30' day
group by date(`datetime`)
)
vkp's answer is basically correct, although there's no need for subquery to select the final result from - you can just put other columns straight into your query, up to something like this:
select *, max(datetime)
from tablename
where datetime >= date(now())-interval '30' day
group by date(datetime);
Ah, and that works for joins too.
The other thing I'd change to address the goal more precise, is:
max(time(datetime))
select * from your_table
where datetime between sysdate and sysdate-30
how to add query result as current date and less days. do not want fixed days pl help in mysql
select
Winner,
Coupon,
DATE_FORMAT(date, '%d-%m-%Y') AS `Date`
FROM table2
ORDER BY DATE_FORMAT(date, '%d-%m-%Y')
LIMIT 1, 30
You can add a where clause to that statement and use <= now() to get the rows less than or equal to the current datetime.
select
Winner,
Coupon,
DATE_FORMAT(date, '%d-%m-%Y') AS `Date`
FROM table2
where datecolumn<=now()
ORDER BY DATE_FORMAT(date, '%d-%m-%Y')
You can use limit 1 to return just one row. http://dev.mysql.com/doc/refman/5.7/en/select.html
Your current limit statement, LIMIT 1, 30, is returning the second row though the thirty first row (the first value is the offset, the second is the number of rows).
I have a query that's meant to return various statistics related to items released within some time period between yesterday and the first of the month last year. For the most part, the following query works as expected.
SELECT DATE_FORMAT(A.ReleaseDate, '%Y-%m') AS FormattedReleaseDate, COUNT(*) AS ReleaseCount, SUM(A.SalesPrice)/COUNT(*) AS MAPAvg, SUM(B.TotalCost)/COUNT(*) AS COGSAvg
FROM item_info A, status B
WHERE A.ReleaseDate BETWEEN '2015-02-01' AND '2016-02-22'
AND A.ListID = B.ListID
GROUP BY MONTH(A.ReleaseDate)
ORDER BY FormattedReleaseDate DESC
This retrieves the specified statistics for every month between 2/1/15 and 2/22/16. However, it's not returning anything from this month. Just to check, I ran this exact same query, replacing the start date above with 2016-02-01, which retrieved the results I expected for just this month. Out of desperation I tried using a different column from item_info that serves the same purpose as status' TotalCost column, thereby alleviating the need for any sort of table join, but I'm still not getting the results from this month. I know it exists and falls within the date range. What exactly is wrong with my first query? I haven't specified a limit to the number of results.
First, you should:
group by FormattedReleaseDate
So if month is repeated in two different years shows as many rows as different pairs month-year are (and not stacking them together in one month, just giving you 12 rows as much).
You should try also:
WHERE STR_TO_DATE(A.ReleaseDate, '%Y-%m-%d')
between STR_TO_DATE('01/02/2015 00:00:00', '%c/%e/%Y %H:%i:%s')
and STR_TO_DATE('22/02/2016 23:59:59', '%c/%e/%Y %H:%i:%s')
just to ensure your filter is more accurate.
So the entire query would be:
SELECT DATE_FORMAT(A.ReleaseDate, '%Y-%m') AS FormattedReleaseDate, COUNT(*) AS ReleaseCount, SUM(A.SalesPrice)/COUNT(*) AS MAPAvg, SUM(B.TotalCost)/COUNT(*) AS COGSAvg
FROM item_info A, status B
WHERE
STR_TO_DATE(A.ReleaseDate, '%Y-%m-%d')
between STR_TO_DATE('01/02/2015 00:00:00', '%c/%e/%Y %H:%i:%s')
and STR_TO_DATE('22/02/2016 23:59:59', '%c/%e/%Y %H:%i:%s')
AND A.ListID = B.ListID
GROUP BY FormattedReleaseDate
ORDER BY FormattedReleaseDate DESC
I wasn't grouping the data properly.
SELECT DATE_FORMAT(A.ReleaseDate, '%Y-%m') AS FormattedReleaseDate, COUNT(*) AS ReleaseCount, SUM(A.SalesPrice)/COUNT(*) AS MAPAvg, SUM(B.TotalCost)/COUNT(*) AS COGSAvg
FROM item_info A, inventory_status B
WHERE A.ListID = B.ListID
AND A.ReleaseDate BETWEEN '$startDate' AND '$endDate'
AND A.HideInDealerPricelist = 0
GROUP BY YEAR(A.ReleaseDate), MONTH(A.ReleaseDate)
ORDER BY FormattedReleaseDate DESC