0

I'm using the below MySQL found on the web to generate a list of dates. However, I want it to generate a list of date_times by minute, E.G yyyy-mm-dd hh:mm:ss. Is this possible? I can't wrap my head around how the existing SQL generates the list nevermind adding minutes!

I need this for my base query for a chart / graph, using left join to pull in data from elsewhere.

Thanks

select * from 
(select adddate('1970-01-01',t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i) selected_date from
 (select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,
 (select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,
 (select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,
 (select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,
 (select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) v
where selected_date between '2019-01-01' and '2019-01-15'

Current output:

selected_date
---
2019-01-01
2019-01-02
2019-01-03
2019-01-04

Desired output:

selected_date
---
2019-01-19 00:05:00
2019-01-19 00:06:00
2019-01-19 00:07:00
2019-01-19 00:08:00
2019-01-19 00:09:00
2019-01-19 00:10:00
2019-01-19 00:11:00

Edit: This is my SQL query serving the graph. I get 5-6 temperature records per minute, so I'm averaging them. My problem is sometimes a temperature probe drops off, so a.date_time or b.date_time doesn't have a consecutive date_time for every single minute

    select 
        b.date_time,
        a.temperature as fishtank,
        b.temperature as room
    from (
        select
            serial,
            convert((min(date_time) div 100)*100, datetime)  as date_time, 
            avg(temperature) as temperature
        from
            raspicontroller.temperature
        WHERE 
            date_time between '$date_from' and '$date_to' and 
            serial like '28-000898430d59'
        group by 
            date_time div 100
    ) a
    right join (
        select
            serial,
            convert((min(date_time) div 100)*100, datetime)  as date_time, 
            avg(temperature) as temperature
        from
            raspicontroller.temperature
        WHERE 
            date_time between '$date_from' and '$date_to' and 
            serial like '28-000f9843201e'
        group by 
            date_time div 100
    ) b on a.date_time = b.date_time

Edit again: I've not managed to generate what I wanted, however I've come up with this which uses existing values in the DB to list dates. I think this will work for me

SELECT
    a.date_time,
    b.temperature as FishTank,
    c.temperature as Room
FROM (
    select
        convert((min(date_time) div 100)*100, datetime)  as date_time
    from
        raspicontroller.temperature
    group by 
        date_time div 100
) as a
LEFT JOIN (
    select
        serial,
        convert((min(date_time) div 100)*100, datetime)  as date_time, 
        avg(temperature) as temperature
    from
        raspicontroller.temperature
    WHERE
        serial like '28-000898430d59'
    group by 
        date_time div 100
) as b on a.date_time = b.date_time
LEFT JOIN (
    select
        serial,
        convert((min(date_time) div 100)*100, datetime)  as date_time, 
        avg(temperature) as temperature
    from
        raspicontroller.temperature
    WHERE
        serial like '28-000f9843201e'
    group by 
        date_time div 100
) as c on a.date_time = c.date_time
Daniel
  • 129
  • 1
  • 5
  • This is for a chart or graph, so you're using some kind of presentation layer. It's far better to handle the display logic there. – Strawberry Jan 19 '19 at 09:42
  • I'm not sure what you mean. I'm running a SQL query, converting the output to a google datatable, then plotting the data in a google chart. I get temperature values every 5 seconds in my database, so I'm averaging the values every minute and performing a join. My issue, is sometimes I don't get a value for 10 minutes or so, which means my join doesn't function as expected – Daniel Jan 19 '19 at 10:38

1 Answers1

0

based on this answer https://stackoverflow.com/a/2157776/834280

SET @end_date := curdate();
SET @start_date := curdate() - INTERVAL 1 WEEK;

SELECT a.dates
FROM (
    SELECT TIMESTAMP(@start_date)
        + INTERVAL (units.mul + (10 * tens.mul) + (100 * hundreds.mul) + (1000 * thousands.mul)) DAY
        + INTERVAL hours.mul HOUR
        + INTERVAL minutes.mul MINUTE
    AS dates
    FROM       (SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS units
    CROSS JOIN (SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS tens
    CROSS JOIN (SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS hundreds
    CROSS JOIN (SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS thousands
    CROSS JOIN (
        SELECT 0 AS mul
        UNION ALL SELECT 1
        UNION ALL SELECT 2 
        UNION ALL SELECT 3 
        UNION ALL SELECT 4 
        UNION ALL SELECT 5 
        UNION ALL SELECT 6 
        UNION ALL SELECT 7 
        UNION ALL SELECT 8 
        UNION ALL SELECT 9 
        UNION ALL SELECT 10 
        UNION ALL SELECT 11 
        UNION ALL SELECT 12 
        UNION ALL SELECT 13 
        UNION ALL SELECT 14 
        UNION ALL SELECT 15 
        UNION ALL SELECT 16 
        UNION ALL SELECT 17 
        UNION ALL SELECT 18 
        UNION ALL SELECT 19 
        UNION ALL SELECT 20 
        UNION ALL SELECT 21 
        UNION ALL SELECT 22 
        UNION ALL SELECT 23
    ) AS hours
    CROSS JOIN (
        SELECT 0 AS mul
        UNION ALL SELECT 1
        UNION ALL SELECT 2
        UNION ALL SELECT 3
        UNION ALL SELECT 4
        UNION ALL SELECT 5
        UNION ALL SELECT 6
        UNION ALL SELECT 7
        UNION ALL SELECT 8
        UNION ALL SELECT 9
        UNION ALL SELECT 10
        UNION ALL SELECT 11
        UNION ALL SELECT 12
        UNION ALL SELECT 13
        UNION ALL SELECT 14
        UNION ALL SELECT 15
        UNION ALL SELECT 16
        UNION ALL SELECT 17
        UNION ALL SELECT 18
        UNION ALL SELECT 19
        UNION ALL SELECT 20
        UNION ALL SELECT 21
        UNION ALL SELECT 22
        UNION ALL SELECT 23
        UNION ALL SELECT 24
        UNION ALL SELECT 25
        UNION ALL SELECT 26
        UNION ALL SELECT 27
        UNION ALL SELECT 28
        UNION ALL SELECT 29
        UNION ALL SELECT 30
        UNION ALL SELECT 31
        UNION ALL SELECT 32
        UNION ALL SELECT 33
        UNION ALL SELECT 34
        UNION ALL SELECT 35
        UNION ALL SELECT 36
        UNION ALL SELECT 37
        UNION ALL SELECT 38
        UNION ALL SELECT 39
        UNION ALL SELECT 40
        UNION ALL SELECT 41
        UNION ALL SELECT 42
        UNION ALL SELECT 43
        UNION ALL SELECT 44
        UNION ALL SELECT 45
        UNION ALL SELECT 46
        UNION ALL SELECT 47
        UNION ALL SELECT 48
        UNION ALL SELECT 49
        UNION ALL SELECT 50
        UNION ALL SELECT 51
        UNION ALL SELECT 52
        UNION ALL SELECT 53
        UNION ALL SELECT 54
        UNION ALL SELECT 55
        UNION ALL SELECT 56
        UNION ALL SELECT 57
        UNION ALL SELECT 58
        UNION ALL SELECT 59
    ) AS minutes
) a
WHERE a.dates <= TIMESTAMP(@end_date)
ORDER BY a.dates ASC;
WiR3D
  • 1,465
  • 20
  • 23