My table is defined as follows:
DATETIME ENERGY VALUE
01/01/2013 00:00:00 1000
...
01/01/2013 08:00:00 2000
...
06/30/2013 00:00:00 10000
...
06/30/2013 08:00:00 12000
I need to calculate total energy value between: start hour of 00:00:00 and end hour 08:00:00 in a single day then sum these values for date range between 01/01/2013 and 06/30/2013.
Any idea will be appreciated.
Pseudo code:
SELECT SUM(DAILYENERGYSUM)
FROM
(SELECT SUM(ENGERGY) as DAILYENERGYSUM
FROM TABLE
WHERE DATEPART(DATETIME) >= '1/1/2013' and DATEPART(DATETIME) <= '6/30/2013' and TIMEPART(DATETIME) >= 0 and TIMEPART(DATETIME) <= 8
GROUP BY DATEPART(DATETIME)) AS DAYSUMS
Related
I have a table with start and end field with values such as:
start | end
2021-09-24 17:00:00 | 2021-10-01 08:00:00
I have gone foggy headed and can't figure out why this statement results in nothing:
SELECT *
FROM `oncall`
WHERE `start` >= '2021-10-01 02:00:00'
AND `end` <= '2021-10-01 08:00:00'
although the date range in my example row contains the above range.
I am trying to find any row that overlaps the start and end of the values in the database.
Looking at the entry in your database and the query you're using, it seems like you're actually looking for a date interval overlap query i.e. a query that checks if [2021-10-01 02:00:00, 2021-10-01 08:00:00) overlaps [2021-09-24 17:00:00, 2021-10-01 08:00:00) somehow.
SELECT *
FROM `oncall`
WHERE #d2 > `start` AND `end` > #d1
-- replace #d1 and #d2 with actual values
Note that this query works for all kinds of overlap. For example if you have this pair of dates in your database:
2021-10-11 | 2021-10-15
then all of these input pairs will match:
2021-10-01 | 2021-10-12
2021-10-14 | 2021-10-20
2021-10-01 | 2021-10-20
2021-10-11 | 2021-10-14
DB-Fiddle
CREATE TABLE PaL (
id SERIAL PRIMARY KEY,
event_date DATE
);
INSERT INTO PaL
(event_date)
VALUES
('2020-01-01'),
('2020-02-05'),
('2020-03-20'),
('2020-04-15'),
('2020-05-11'),
('2020-06-18'),
('2020-07-19'),
('2020-12-31');
Expected Result:
first_date_of_the_month first_timestamp_of_the_month
2020-01-01 2020-01-01 00:00:00
2020-02-01 2020-02-01 00:00:00
2020-03-01 2020-03-01 00:00:00
2020-04-01 2020-04-01 00:00:00
2020-05-01 2020-05-01 00:00:00
2020-06-01 2020-06-01 00:00:00
2020-07-01 2020-07-01 00:00:00
2020-12-01 2020-12-01 00:00:00
I want to extract the first date and first timestamp of each event_date in the table.
I am doing this with the below query:
SELECT
DATE_ADD(DATE_ADD(LAST_DAY(pl.event_date), INTERVAL 1 DAY), INTERVAL -1 MONTH) AS first_date_of_the_month,
DATE_FORMAT(DATE_ADD(DATE_ADD(LAST_DAY(pl.event_date), INTERVAL 1 DAY), INTERVAL -1 MONTH), '%Y-%m-%d %H:%i:%s') AS first_timestamp_of_the_month
FROM PaL pl
However, HeidiSQL is somehow interpeting the timestamp as value and not as a TIMESTAMP format.
How do I need to change the query so it displays the result as TIMESTAMP?
SELECT *,
DATE_FORMAT(event_date, '%Y-%m-01') AS first_date_of_the_month,
DATE_FORMAT(event_date, '%Y-%m-01 00:00:00') AS first_timestamp_of_the_month
FROM PaL
HeidiSQL is somehow interpeting the timestamp as value and not as a TIMESTAMP format.
This is client problem.
MySQL's datatype system is soft, i.e. each value is converted to needed datatype according to current datatype context implicitly. But you may use correct final context or excplicit final CAST.
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=21a7d3fccaca1329ef8e1797d366c5a6
You don't have to convert to strings to accomplish this. It is simple enough with basic date functions:
SELECT event_date + interval (1 - day(event_date)) day as first_date_of_the_month,
timestamp(event_date + interval (1 - day(event_date)) day) as first_timestamp_of_the_month
FROM PaL pl;
Here is a db<>fiddle.
Gotta chime in here.... The way I prefer in MySQL, the way that uses the inbuilt LAST_DAY() function, is this:
SELECT LAST_DAY(event_date) + INTERVAL 1 DAY - INTERVAL 1 MONTH
For what it's worth the string constants 2021-03-13 00:00:00 and the shorter 2021-03-13 have precisely the same meaning when used as DATE, DATETIME, or TIMESTAMP values. There's little need for a separate first_timestamp_of_the_month value.
It works in Oracle too. In SQL Server, it's EOMONTH(). postgreSQL, not so much.
I am working in mySQL and I currently have a count of total orders by day, but I would like to add Saturday and Sunday orders to Monday then remove Saturday and Sunday values. I have done some research on this but I cannot seem to find anything similar to what I am trying to do.
My current data table looks like this:
Date | Daily Count
8-6-2020 25
8-7-2020 82
8-8-2020 24
8-9-2020 33
8-10-2020 18
8-11-2020 10
8-12-2020 25
8-13-2020 15
I need it to look something like this:
Date | Daily Count
8-6-2020 25
8-7-2020 82
8-10-2020 75
8-11-2020 10
8-12-2020 25
8-13-2020 15
In this one the Daily counts for the 8th and 9th are added to the 10th, then removed, because they are weekend days. Thank you in advance for your help!
Consider using a case expression to adjust the date:
select
case weekday(date)
when 5 then date + interval 2 day
when 6 then date + interval 1 day
else date
end as new_date,
sum(daily_count) as daily_count
from mytable
group by new_date
I was writing a mini scheduler that perform certain task.
For calculating trigger time, I am using MYSQL. I am stucked at writing one of the query.
Find immediate DateTime which is greater than the given prevtime,
AND
the Day of the required immediate datetime should be ANY of given days
AND
time(HH:MM:SS) portion of required immediate datetime should be equal to given time.
Examples:
(a)
If given days are ('MON', 'WEDNES', 'SAT'),
given time is 10:15:00,
given prevtime is 2014-11-12 23:17:00
Then MYSQL should return
2014-11-15 10:15:00
(b)
Given Days: ('SUN','SAT','TUES')
Given Time: 09:10:00
Given prevtime is 2014-11-30 07:05:12
MYSQL should return 2014-11-30 09:10:00
(c)
Given Days: ('MON','THURS','SAT')
Given Time: 11:00:00
Given prevtime is 2014-12-29 11:55:12
MYSQL should return 2015-01-01 11:00:00
(d)
Days: (SUN, THURS, SAT)'
Given prevtime is 2014-02-27 18:15:00
Given Time 15:15:00
MYSQL Query result: 2014-03-01 15:15:00
(e)
DAYS: (TUES, WED, FRI)
Prev Date: 2014-12-23 09:30:00
Time : 08:00:00
Expected Result:
2014-12-24 08:00:00
(f)
DAYS: SUN, TUES, THURS
Prev Date: 2014-07-31 10:10:00
Time: 06:07:08
Expected Res:
2014-08-03 06:07:08
Using numeric weekday numbers, 0=Monday, 6=Sunday:
set #day1=0;
set #day2=2;
set #day3=5;
set #time=time('10:15:00');
set #prevtime=timestamp('2014-11-12 23:17:00');
select if(weekday(#nexttime:=date_add(concat(date(#prevtime),' ',#time),interval if(#time>time(#prevtime),0,1) day)) in (#day1,#day2,#day3),#nexttime,if(weekday(#nexttime:=date_add(#nexttime,interval 1 day)) in (#day1,#day2,#day3),#nexttime,if(weekday(#nexttime:=date_add(#nexttime,interval 1 day)) in (#day1,#day2,#day3),#nexttime,if(weekday(#nexttime:=date_add(#nexttime,interval 1 day)) in (#day1,#day2,#day3),#nexttime,if(weekday(#nexttime:=date_add(#nexttime,interval 1 day)) in (#day1,#day2,#day3),#nexttime,if(weekday(#nexttime:=date_add(#nexttime,interval 1 day)) in (#day1,#day2,#day3),#nexttime,date_add(#nexttime,interval 1 day))))))) as nexttime;
If you have only one weekday, you can set all three variables to the same number.
You should be able to formulate the where clause using the DAYNAME(), HOUR(), MINUTE() and SECOND() functions:
https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html
If performance is inadequate and you start wishing you could index on DAYNAME(columname) for example, you can consider denormalizing your data and storing the DAYNAME value separately.
It might be simpler to switch to Postgres at that point though:
http://www.postgresql.org/docs/9.1/static/indexes-expressional.html
I've written some SQL to give me a range of dates between two times like so:
select date_add(x.min_date, interval ((t500.id-1) * 30) minute) period
from (
select '2013-08-05T23:00' as min_date, '2013-08-06T01:00' as max_date
) x,
t500
where date_add(x.min_date, interval ((t500.id-1) * 30) minute) <= x.max_date);
Where T500 is a trivial table with column id of 1 to 500 I use for simulating a loop.
Now I expect this to return:
2013-08-05 23:00:00
2013-08-05 23:30:00
2013-08-06 00:00:00
2013-08-06 00:30:00
2013-08-06 01:00:00
and finish there. But instead it carries on until 2013-08-06 23:30:00. I tried different max dates and it always returns dates to the end of the day. Could someone explain what's happening and how to make it stop when I want?
First thing that comes to mind would be casting your date strings into a date format instead of a string for example:
cast('2013-08-05T23:00' as smalldatetime)