I have a time range entity with start and end datetime column.
I need to find the maximum occurrencies (count) of overlapping the same time slot.
In the example above, the count is 4.
https://www.db-fiddle.com/f/pcq1MjQeqSEMDdyGxkFsR5/0
Probably I need some recurring query but I don't know how to start.
For MySQL 5.x:
SELECT SUM(points2.weight) max_weight
FROM (
SELECT start dt FROM slots
UNION DISTINCT
SELECT `end` FROM slots
) points1
JOIN (
SELECT dt, SUM(weight) weight
FROM (
SELECT start dt, 1 weight FROM slots
UNION ALL
SELECT `end`, -1 FROM slots
) points
GROUP BY dt
) points2 ON points1.dt >= points2.dt
GROUP BY points1.dt
ORDER BY max_weight DESC LIMIT 1
https://dbfiddle.uk/f0b56Q4X (step-by-step, with comments)
I have this query and I want to select the currentprice(the most current price sorted by time) and the oldprice(the last row sorted by time) in the same columns per row. I figured out how to select the currentprice but how can I select both in the same query?
In the end I want to make a calculation for the percentage of gain or drop with ROUND((latestprice - oldprice) / oldprice * 100, 2) as gain_ratio
WITH tmp AS (
SELECT TrackID, ID, price, MAX(Time) as maxtime, MIN(Time) as mintime
FROM track
WHERE Time > NOW() - INTERVAL 1 HOUR
GROUP BY ID
)
SELECT T.TrackID, T.ID, tmp.Price as currentprice, T.Time
FROM track AS T
JOIN tmp ON T.ID = tmp.ID
WHERE T.Time = tmp.maxtime;
I'm really struggeling to grasp how to make a CTE query, I have read the documentation several times
Have you tried to change your where clause to...?:
WHERE T.Time = tmp.maxtime or T.Time = tmp.mintime
If i have a database with 2 columns, date and account and i want to first count account per day and then group by week. How wrong is my code and how to do it?
I edited my code a little bit, i was not thinking right from the beginning. I want the sum to be 9 for week 48.
SELECT date, account,
(SELECT date, COUNT(DISTINCT account)
FROM t1
GROUP BY date
) AS sum
FROM t1
GROUP BY YEARWEEK(date)
You seem to be looking for a simple aggregate query with count(distinct ...):
select yearweek(date) year_week, count(distinct account) cnt_account
from t1
group by yearweek(date)
order by year_week
Note: yearweek() gives you the year and week; this is better than week(), if your data spreads over several years.
EDIT
From the comments, you need two levels of aggregation:
select yearweek(dy) year_week, sum(cnt) cnt_account
from (
select date(t1.date) dy, count(distinct t1.account) cnt
from t1
group by date(t1.date)
) t
group by yearweek(dy)
order by year_week
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;
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).