Using grouped value instead of table value in MySQL query - mysql

I need to group some data by date, but I have a very special case where the name of the final field should be the same of the original field and I can't use an expression in the GROUP BY
I have created this sqlfiddle with some example data:
http://sqlfiddle.com/#!2/8771a/1
I need this result:
DATE PAGEVIEWS
2013-12 69
2013-11 70
Note 1: I can't change the group by, if I do this I get the result, but I need to group by date and date should be the formatted date, and not the real date in the table:
SELECT DATE_FORMAT(`date`, "%Y-%m") AS `date`, SUM(pageviews) AS pageviews
FROM `domains_data`
GROUP BY DATE_FORMAT(`date`, "%Y-%m")
ORDER BY `date` DESC
Note 2: I can't rename the field, it should have the name "date" at the end, this isn't possible for me:
SELECT DATE_FORMAT(`date`, "%Y-%m") AS `date2`, SUM(pageviews) AS pageviews
FROM `domains_data`
GROUP BY `date2`
ORDER BY `date` DESC
There is some way to do it with MySQL?

Is the use of nested query allowed?
SELECT `date`, SUM(pageviews) AS pageviews FROM
(SELECT DATE_FORMAT(`date`, "%Y-%m") AS `date`, SUM(pageviews) AS pageviews
FROM `domains_data`
GROUP BY `date`) AS Ref
GROUP BY `date`
ORDER BY `date` DESC

If you can change the from clause:
SELECT `date`, SUM(pageviews) AS pageviews
FROM (select DATE_FORMAT(`date`, "%Y-%m") AS `date`, pageviews
from `domains_data` dd
) dd
GROUP BY `date`
ORDER BY `date` DESC;
However, given the constraint that you cannot change the group by, you probably cannot change the from either. Can you explain why your query has these limitations?

Related

MySQL nested query based on the last 10 dates

I have a database that stores the temperature reading of each sensor in a along with the sensor ID, and date the reading was taken.
SELECT DISTINCT `date` FROM `temperatureData` ORDER BY `date` ASC LIMIT 10
this allows me to select the last 10 readings that are going to be plotted in a chart.
there are up to 40 sensor readings for each date.
I tried doing the following.
SELECT `date`, `sensor`, `temp`
FROM `temperatureData`
WHERE `date` = (
SELECT DISTINCT `date` FROM `temperatureData` ORDER BY `date` ASC LIMIT 10
)
Can anyone assist me as to how to select all the readings for the dates that are returned back from the last 10 dates?
Thanks in advance.
Boris
You just need in instead of =:
SELECT `date`, `sensor`, `temp`
FROM `temperatureData`
WHERE `date` IN (
SELECT DISTINCT `date` FROM `temperatureData` ORDER BY `date` DESC LIMIT 10
)
NB: if you want the readings of the last 10 dates, you probably want to ORDER BY date DESC instead of ASC. I changed that too.
In MySQL 8.0, this could also be rewritten with window function dense_rank():
SELECT `date`, `sensor`, `temp`
FROM (
SELECT
`date`,
`sensor`,
`temp`
DENSE_RANK() OVER(ORDER BY `date` DESC) rn
FROM `temperatureData`
) t
WHERE rn <= 10
Edit
To workaround the limitation of MySQL 5.7 not supporting LIMIT in subqueries with IN, you can use a join instead:
SELECT t.`date`, t.`sensor`, t.`temp`
FROM `temperatureData` t
INNER JOIN (
SELECT DISTINCT `date` FROM `temperatureData` ORDER BY `date` DESC LIMIT 10
) d ON d.`date` = t.`date`

Simple query to find the employee id, date and minimum_time and maximum_time order by id,date,time

How can i find the employee id, date and minimum_time and maximum_time order by id,date,time from this table?
SELECT emp_id,
date,
MIN(time) AS in_time,
MAX(time) AS out_time
FROM yourTable
GROUP BY emp_id,
date
ORDER BY emp_id, date
The MIN() and MAX() functions will find the earliest and latest time of each employee, on each date.
It's simple your query syntax would be like
SELECT atr1, atr2,.. FROM table_name ORDER BY atr1, atr2,..
Try:
SELECT `emp_id` , `date` , MIN( `time` ) as in_time , MAX( `time` ) as out_time
FROM `Table`
WHERE 1
GROUP BY `date`
ORDER BY `time` DESC
LIMIT 0 , 30
As i can see there are same emp_id for many dates, so group by date will get all data for each date.
You can just use the SELECT Query
SELECT employee.id, employee.date, employee.minimum_time, employee.maximum_time
From table_name
ORDER BY employee.id

Reverse order for GROUP BY in MySQL

I need to select first value for every hour from my db. But I don't know how to reverse order on GROUP BY statement.
How can i rewrite my query (now it selects last value in hour)?
SELECT HOUR(`time`) as hour, mytable.*
FROM mytable
WHERE DATE(`time`) ="2015-09-12" GROUP BY HOUR(`time`) ORDER BY `time` ASC;
This query gave me expected result:
SELECT HOUR(`time`) as hour, sortedTable.* FROM
(SELECT electrolysis.* FROM electrolysis
WHERE DATE(`time`)='2015-09-12' ORDER BY `time`) as sortedTable
GROUP BY HOUR(`time`);
You can just select the MIN HOUR in sub query , try using the query:
SELECT * from mytable WHERE `time` IN (
SELECT MIN(HOUR(`time`)) as `hour`
FROM mytable
WHERE DATE(`time`) ="2015-09-12"
GROUP BY HOUR(`time`) ) ORDER BY `time` ASC;
You can do something like this:-
SELECT sub0.min_time,
mytable.*
FROM mytable
INNER JOIN
(
SELECT MIN(`time`) AS min_time
FROM mytable
GROUP BY HOUR(`time`)
) sub0
ON mytable.`time` = sub0.min_time
WHERE DATE(`time`) ="2015-09-12"
ORDER BY `time` ASC
This is using a sub query to get the smallest time in each hour. This is then joined back against your main table on this min time to get the record that has this time.
Note that there is a potential problem here if there are multiple records that share the same time as the smallest one for an hour. There are ways around this, but that will depend on your data (eg, if you have a unique id field which is always ascending with time then you could select the min id for each hour and join based on that)
You can use below query, which is more optimized just make sure that time field should be indexed.
SELECT HOUR(m.time), m.*
FROM mytable AS m
JOIN
(
SELECT MIN(`time`) AS tm
FROM mytable
WHERE `time` >= '2015-09-12 00:00:00' AND `time` <= '2015-09-12 23:59:59'
GROUP BY HOUR(`time`)
) AS a ON m.time=a.tm
GROUP BY HOUR(m.time)
ORDER BY m.time;

MySQL - How to select rows with the min(timestamp) per hour of a given date

I have a table of production readings and need to get a result set containing a row for the min(timestamp) for EACH hour.
The column layout is quite simple:
ID,TIMESTAMP,SOURCE_ID,SOURCE_VALUE
The data sample would look like:
123,'2013-03-01 06:05:24',PMPROD,12345678.99
124,'2013-03-01 06:15:17',PMPROD,88888888.99
125,'2013-03-01 06:25:24',PMPROD,33333333.33
126,'2013-03-01 06:38:14',PMPROD,44444444.44
127,'2013-03-01 07:12:04',PMPROD,55555555.55
128,'2013-03-01 10:38:14',PMPROD,44444444.44
129,'2013-03-01 10:56:14',PMPROD,22222222.22
130,'2013-03-01 15:28:02',PMPROD,66666666.66
Records are added to this table throughout the day and the source_value is already calculated, so no sum is needed.
I can't figure out how to get a row for the min(timestamp) for each hour of the current_date.
select *
from source_readings
use index(ID_And_Time)
where source_id = 'PMPROD'
and date(timestamp)=CURRENT_DATE
and timestamp =
( select min(timestamp)
from source_readings use index(ID_And_Time)
where source_id = 'PMPROD'
)
The above code, of course, gives me one record. I need one record for the min(hour(timestamp)) of the current_date.
My result set should contain the rows for IDs: 123,127,128,130. I've played with it for hours. Who can be my hero? :)
Try below:
SELECT * FROM source_readings
JOIN
(
SELECT ID, DATE_FORMAT(timestamp, '%Y-%m-%d %H') as current_hour,MIN(timestamp)
FROM source_readings
WHERE source_id = 'PMPROD'
GROUP BY current_hour
) As reading_min
ON source_readings.ID = reading_min.ID
SELECT a.*
FROM Table1 a
INNER JOIN
(
SELECT DATE(TIMESTAMP) date,
HOUR(TIMESTAMP) hour,
MIN(TIMESTAMP) min_date
FROM Table1
GROUP BY DATE(TIMESTAMP), HOUR(TIMESTAMP)
) b ON DATE(a.TIMESTAMP) = b.date AND
HOUR(a.TIMESTAMP) = b.hour AND
a.timestamp = b.min_date
SQLFiddle Demo
With window function:
WITH ranked (
SELECT *, ROW_NUMBER() OVER(PARTITION BY HOUR(timestamp) ORDER BY timestamp) rn
FROM source_readings -- original table
WHERE date(timestamp)=CURRENT_DATE AND source_id = 'PMPROD' -- your custom filter
)
SELECT * -- this will contain `rn` column. you can select only necessary columns
FROM ranked
WHERE rn=1
I haven't tested it, but the basic idea is:
1) ROW_NUMBER() OVER(PARTITION BY HOUR(timestamp) ORDER BY timestamp)
This will give each row a number, starting from 1 for each hour, increasing by timestamp. The result might look like:
|rest of columns |rn
123,'2013-03-01 06:05:24',PMPROD,12345678.99,1
124,'2013-03-01 06:15:17',PMPROD,88888888.99,2
125,'2013-03-01 06:25:24',PMPROD,33333333.33,3
126,'2013-03-01 06:38:14',PMPROD,44444444.44,4
127,'2013-03-01 07:12:04',PMPROD,55555555.55,1
128,'2013-03-01 10:38:14',PMPROD,44444444.44,1
129,'2013-03-01 10:56:14',PMPROD,22222222.22,2
130,'2013-03-01 15:28:02',PMPROD,66666666.66,1
2) Then on the main query we select only rows with rn=1, in other words, rows that has lowest timestamp in each hourly partition (1st row after sorted by timestamp in each hour).

Most common hour query?

I have this table:
ID(INT) DATE(DATETIME)
Under the DATE column there are a lot of different dates, and I want to figure out the most common hour between all the rows of the table, regardless of the day.
How can I do that with a MySQL query?
SELECT HOUR(date) AS hr, COUNT(*) AS cnt
FROM yourtable
GROUP BY hr
ORDER BY cnt DESC
LIMIT 1
relevant docs: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_hour
Try this -
SELECT HOUR(`DATE`) AS `hour`, COUNT(*)
FROM `table`
GROUP BY `hour`
You could do a query like:
SELECT COUNT(daterow) AS occurrences FROM table GROUP BY daterow ORDER BY occurrences DESC LIMIT 1;
SELECT COUNT( id ) , HOUR( date )
FROM test
GROUP BY HOUR( date )
ORDER BY COUNT( id ) DESC
LIMIT 1