I want to average every hour data from 2 table (cuaca and data_monitoring) in MySQL then insert the result in another table (average) but my code doesn't work. If I just average from one table then insert the result in the another table, the code is working. I use scheduler because I need to know average result every hour
this ini my code, can you help me please?
DELIMITER $$
CREATE
EVENT `otomatis`
ON SCHEDULE EVERY 1 HOUR STARTS '2015-05-20 14:37:00'
DO BEGIN
truncate table average;
INSERT INTO `average`
(`tanggalave`, `avetemp`, `avehumid`,`avewind`)
SELECT `date` , avg(`suhu_udara`), avg(`kelembaban_udara`), avg(`kecepatan_angin`)
FROM `cuaca`
GROUP By DATE( date ), HOUR( date );
INSERT INTO `average`
(`avegel`)
SELECT avg(`tinggi_gelombang`)
FROM `data_monitoring`
GROUP By DATE( date ), HOUR( date );
END $$
DELIMITER ;
Related
Sorry, I have difficulty explaining my question and search for a previous answer. This is my problem -- I have a MySQL table with events
CREATE TABLE events {
id INT,
event INT,
date DATETIME
}
Data is being added a few times a week or month. I would like to see the statistical spread of time between two adjacent events. Something like:
Time difference between two events
1 day appart - 4 occurances
2 days apart - 2 occurances
n days apart - x occurances
It should be something like this, I guess, but calculating the time difference between events.
SELECT COUNT('id') AS 'no', ??? AS 'delta' GROUP BY FLOOR( 'delta' )
This piece of SQL code did it:
SET #old = NOW();
SELECT COUNT(`id`) AS `no`, query1.`delta` FROM
( SELECT `id`, `date`, DATEDIFF( #old, `date` ) AS `delta`, #old := `date` AS `old`
FROM `life`
ORDER BY `date`DESC ) query1
GROUP BY `delta`
ORDER BY `delta`
I need this query:
SELECT ItemID, Price
FROM table
WHERE ItemID = %d
GROUP BY Price
ORDER BY COUNT(*) DESC LIMIT 1
-run once a day, and have the results from it stored in another table with the time stamp of the query.
Is there a way I can automatically query all the available ItemID values? For example, if there are 20 ItemID values available, I need 20 separate queries.
You can use the mysql event scheduler for this. Here's an example with your current query inserting data into a table called "new_table", starting at 3 AM on March 28.
DELIMITER $$
CREATE
EVENT `daily_backup`
ON SCHEDULE EVERY 1 DAY STARTS '2015-03-28 03:00:00'
DO BEGIN
INSERT INTO new_table (ItemID, Price, Time)
SELECT ItemID, Price, NOW()
FROM table
WHERE ItemID = %d
GROUP BY Price
ORDER BY COUNT(*) DESC LIMIT 1;
END */$$
You can do the same thing with your other queries; they can be put into the same event, before the END
I have a mysql table with date column. date column data type is TIMESTAMP and default set to CURRENT_TIMESTAMP which record both date and time
now i want to count my rows under given day
As an example
++++++++++ 8am 9am 10am 11am
++user1+++ 15 10 11 10
++user2+++ 10 10 20 30
Every hour count should be recorded separately like this.
i tried with this but it's not working
SELECT COUNT(*) FROM mytable
WHERE `date` = '2015-01-26'
GROUP BY HOUR(`TIMESTAMP`)
how can i achieve this ?
i have no idea how to group with user . sproc is also okay
I made a sproc like this. but this sproc contain errors. can some one please help me now i want to count this separated by 9 hours
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `test22`(IN datestamp DATE)
BEGIN
SELECT username,
COUNT(if(disblid,1,null)) '8:00 AM', where time between '08:00' and '09:00':
COUNT(if(disblid,1,null)) '9:00 AM' , where time between '09:00' and '10:00';
FROM claimloans
WHERE DATE(date) = datestamp
group by Username;
END
Thanks for everyone who helped me I come up with sproc that working perfectly fine.
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `claimscounter`(IN datestamp DATE)
BEGIN
SELECT username,
COUNT(IF(HOUR(date)=0,1,NULL)) AS '12am',
COUNT(IF(HOUR(date)=1,1,NULL)) AS '1am',
COUNT(IF(HOUR(date)=2,1,NULL)) AS '2am',
COUNT(IF(HOUR(date)=3,1,NULL)) AS '3am',
COUNT(IF(HOUR(date)=4,1,NULL)) AS '4am',
COUNT(IF(HOUR(date)=5,1,NULL)) AS '5am',
COUNT(IF(HOUR(date)=6,1,NULL)) AS '6am',
COUNT(IF(HOUR(date)=7,1,NULL)) AS '7am',
COUNT(IF(HOUR(date)=8,1,NULL)) AS '8am',
COUNT(IF(HOUR(date)=9,1,NULL)) AS '9am',
COUNT(IF(HOUR(date)=10,1,NULL)) AS '10am',
COUNT(IF(HOUR(date)=11,1,NULL)) AS '11am',
COUNT(IF(HOUR(date)=12,1,NULL)) AS '12pm',
COUNT(IF(HOUR(date)=13,1,NULL)) AS '1pm',
COUNT(IF(HOUR(date)=14,1,NULL)) AS '2pm',
COUNT(IF(HOUR(date)=15,1,NULL)) AS '3pm',
COUNT(IF(HOUR(date)=16,1,NULL)) AS '4pm',
COUNT(IF(HOUR(date)=17,1,NULL)) AS '5pm',
COUNT(IF(HOUR(date)=18,1,NULL)) AS '6pm',
COUNT(IF(HOUR(date)=19,1,NULL)) AS '7pm',
COUNT(IF(HOUR(date)=20,1,NULL)) AS '8pm',
COUNT(IF(HOUR(date)=21,1,NULL)) AS '9pm',
COUNT(IF(HOUR(date)=22,1,NULL)) AS '10pm',
COUNT(IF(HOUR(date)=23,1,NULL)) AS '11pm'
FROM claimloans
WHERE DATE(date) = datestamp
group by username;
END
But now I have another small problem. This count all the hours. if it's not entry for some hour it count as zero. I want to count hours only have records can someone help me with this
thnaks
I would solve this as a view, like so:
CREATE TABLE foo (id int not null, val timestamp);
CREATE VIEW foo_by_hours AS (
SELECT
id,
DATE(val) AS 'day',
COUNT(IF(HOUR(val)=0,1,NULL)) AS '12am',
COUNT(IF(HOUR(val)=1,1,NULL)) AS '1am',
COUNT(IF(HOUR(val)=2,1,NULL)) AS '2am',
COUNT(IF(HOUR(val)=3,1,NULL)) AS '3am',
...
FROM foo
GROUP BY id, day);
SELECT * FROM foo_by_hours;
Full example on SQL Fiddle
I also added a view which uses SUM instead of COUNT. The result is the same, it's just a different way of doing it.
I am working with MySQL database and I have to generate date intervals for specified period(specified by start and stop date) with specified step(for example one day).
I have written a stored procedure to generate intervals, to create a temporary table and to populate this table with intervals.
DELIMITER $$
CREATE PROCEDURE showu(IN start date, IN stop date)
BEGIN
CREATE TEMPORARY TABLE intervals(single_day DATE);
next_date: LOOP
IF start>stop THEN
LEAVE next_date;
END IF;
INSERT INTO intervals(single_day) VALUES(start);
SET start = DATE_ADD(start, INTERVAL 1 DAY);
END LOOP next_date;
END$$
DELIMITER ;
I want to use this temporary table in join queries. However I faced with a problem. When I call procedure call showu('2008-01-09', '2010-02-09'); it is executing approximately 30 seconds. The question why it is executing so long? Is it possible to improve it? If this solution is wrong how can I resolve my problem in different way?
From comments:
2 big problems: 1. I don't know exactly value of step(one day or one month or one hour).
Create one big table like this once (not temporary):
full_date | year | month | day | full_time | hour | minute | is_weekend | whatever
----------------------------------------------------------------------------------
...
Create as much indexes as needed and you will have a very performant a powerful swiss knife for all sorts of reports.
Note: You might consider not having time and date in the same table. This is just to simplify the example.
Your second problem
I will clog my database with not model data.
is no problem. Databases are there to hold data. That's it. If you have problems with space or whatever, the solution is to get more space, not to limit your ability to work efficiently.
That being said, here's some examples how to use this table.
You need dates:
SELECT
*
FROM
(
SELECT full_date AS your_step
FROM your_new_swiss_army_knife
WHERE `year` = 2012
GROUP BY full_date
) dates
LEFT JOIN your_tables_that_you_want_to_build_a_report_on y ON dates.your_step = y.date
Same with months:
SELECT
*
FROM
(
SELECT CONCAT(year, '-', month) AS your_step
FROM your_new_swiss_army_knife
WHERE full_date BETWEEN this AND that
GROUP BY year, month
) dates
LEFT JOIN your_tables_that_you_want_to_build_a_report_on y ON dates.your_step = CONCAT(YEAR(y.date), '-', MONTH(y.date))
So lets say I have some records that look like:
2011-01-01 Cat
2011-01-02 Dog
2011-01-04 Horse
2011-01-06 Lion
How can I construct a query that will return 2011-01-03 and 2011-01-05, ie the unused dates. I postdate blogs into the future and I want a query that will show me the days I don't have anything posted yet. It would look from the current date to 2 weeks into the future.
Update:
I am not too excited about building a permanent table of dates. After thinking about it though it seems like the solution might be to make a small stored procedure that creates a temp table. Something like:
CREATE PROCEDURE MISSING_DATES()
BEGIN
CREATE TABLE TEMPORARY DATES (FUTURE DATETIME NULL)
INSERT INTO DATES (FUTURE) VALUES (CURDATE())
INSERT INTO DATES (FUTURE) VALUES (ADDDATE(CURDATE(), INTERVAL 1 DAY))
...
INSERT INTO DATES (FUTURE) VALUES (ADDDATE(CURDATE(), INTERVAL 14 DAY))
SELECT FUTURE FROM DATES WHERE FUTURE NOT IN (SELECT POSTDATE FROM POSTS)
DROP TABLE TEMPORARY DATES
END
I guess it just isn't possible to select the absence of data.
You're right — SQL does not make it easy to identify missing data. The usual technique is to join your sequence (with gaps) against a complete sequence, and select those elements in the latter sequence without a corresponding partner in your data.
So, #BenHoffstein's suggestion to maintain a permanent date table is a good one.
Short of that, you can dynamically create that date range with an integers table. Assuming the integers table has a column i with numbers at least 0 – 13, and that your table has its date column named datestamp:
SELECT candidate_date AS missing
FROM (SELECT CURRENT_DATE + INTERVAL i DAY AS candidate_date
FROM integers
WHERE i < 14) AS next_two_weeks
LEFT JOIN my_table ON candidate_date = datestamp
WHERE datestamp is NULL;
One solution would be to create a separate table with one column to hold all dates from now until eternity (or whenever you expect to stop blogging). For example:
CREATE TABLE Dates (dt DATE);
INSERT INTO Dates VALUES ('2011-01-01');
INSERT INTO Dates VALUES ('2011-01-02');
...etc...
INSERT INTO Dates VALUES ('2099-12-31');
Once this reference table is set up, you can simply outer join to determine the unused dates like so:
SELECT d.dt
FROM Dates d LEFT JOIN Blogs b ON d.dt = b.dt
WHERE b.dt IS NULL
If you want to limit the search to two weeks in the future, you could add this to the WHERE clause:
AND d.dt BETWEEN NOW() AND ADDDATE(NOW(), INTERVAL 14 DAY)
The way to extract rows from the mysql database is via SELECT. Thus you cannot select rows that do not exist.
What I would do is fill my blog table with all possible dates (for a year, then repeat the process)
create table blog (
thedate date not null,
thetext text null,
primary key (thedate));
doing a loop to create all dates entries for 2011 (using a program, eg $mydate is the date you want to insert)
insert IGNORE into blog (thedate,thetext) values ($mydate, null);
(the IGNORE keyword to not create an error (thedate is a primary key) if thedate exists already).
Then you insert the values normally
insert into blog (thedate,thetext) values ($mydate, "newtext")
on duplicate key update thetext="newtext";
Finally to select empty entries, you just have to
select thedate from blog where thetext is null;
You probably not going to like this:
select '2011-01-03', count(*) from TABLE where postdate='2011-01-03'
having count(*)=0 union
select '2011-01-04', count(*) from TABLE where postdate='2011-01-04'
having count(*)=0 union
select '2011-01-05', count(*) from TABLE where postdate='2011-01-05'
having count(*)=0 union
... repeat for 2 weeks
OR
create a table with all days in 2011, then do a left join, like
select a.days_2011
from all_days_2011
left join TABLE on a.days_2011=TABLE.postdate
where a.days_2011 between date(now()) and date(date_add(now(), interval 2 week))
and TABLE.postdate is null;