I have the following MySQL table:
+---------------------+-----------+
| timestamp | sensor_id |
+---------------------+-----------+
| 2010-04-09 01:42:31 | M049 |
| 2010-04-09 01:43:31 | M049 |
| 2010-04-09 01:44:31 | M049 |
| 2010-04-09 01:59:31 | M049 |
| 2010-04-10 01:10:31 | M049 |
| 2010-04-10 01:40:31 | M049 |
| 2010-04-10 01:42:31 | M049 |
| 2010-04-11 16:43:31 | M049 |
+---------------------+-----------+
I know how to query the db to get a count of the entries for a specific daytime intervall and group the result by date.
An example to query the event count between 1 am and 2 pm would look like this:
SELECT
date(timestamp) as date,
count(timestamp) as count
FROM
event_data
WHERE
EXTRACT(HOUR FROM TIME(timestamp)) BETWEEN 1 AND 14
GROUP BY
date
The query returns the following table:
+------------+-------+
| date | count |
+------------+-------+
| 2010-04-09 | 4 |
| 2010-04-10 | 3 |
+------------+-------+
Now I only want to count an event every 15 minutes.
The desired result would be:
+------------+-------+
| date | count |
+------------+-------+
| 2010-04-09 | 2 |
| 2010-04-10 | 2 |
+------------+-------+
How do I alter my query to get these results?
You have a good start to group by date and query for the hours you want. Similarly, you can write a query that gets the intervals. I would start by writing a case statement that reads each row you want, and adds a column specifying which interval of the hour it is. (0:14 - 1, 15:29 - 2...) like this:
SELECT timeCol,
HOUR(timeCol) AS hour,
CASE WHEN MINUTE(timeCol) BETWEEN 0 AND 14 THEN 1
WHEN MINUTE(timeCol) BETWEEN 15 AND 29 THEN 2
WHEN MINUTE(timeCol) BETWEEN 30 AND 44 THEN 3
ELSE 4 END AS minute
FROM myTable;
This gives you something like this:
| timeCol | hour | minute |
+---------------------+------+--------+
| 2010-04-09 01:42:31 | 1 | 3 |
| 2010-04-09 01:43:31 | 1 | 3 |
| 2010-04-09 01:44:31 | 1 | 3 |
Once you have that, you can select the distinct hour/minute pairs in each day, and that will give you what you want, as long as you use your WHERE clause accordingly:
SELECT DATE(timeCol) AS dateCol, COUNT(DISTINCT hour, minute) AS numEvents
FROM(
SELECT timeCol,
HOUR(timeCol) AS hour,
CASE WHEN MINUTE(timeCol) BETWEEN 0 AND 14 THEN 1
WHEN MINUTE(timeCol) BETWEEN 15 AND 29 THEN 2
WHEN MINUTE(timeCol) BETWEEN 30 AND 44 THEN 3
ELSE 4 END AS minute
FROM myTable) tmp
WHERE HOUR(timecol) BETWEEN 1 AND 14
GROUP BY dateCol;
Here is an SQL Fiddle example.
I would just like to add that you don't have to record the intervals as 1, 2, 3, 4. Make sure you use something readable, that will make sense to you again in the future. For example, maybe something like this would be better:
WHEN MINUTE(timeCol) BETWEEN 0 and 14 THEN 'firstInterval'...
Related
I have a MySQL table that tracks certain totals by both hour of the day and various locations. I am trying to create a query that will total not only each column, but also each row. The query I have so far totals each column, but I can't figure out how to get a total for each row as well.
This is my query:
SELECT * FROM
(SELECT IFNULL(hour,"Total") as hour, SUM(location1), SUM(location2), SUM(location3), SUM(location4), SUM(location), FROM counts WHERE ay = 'AY1617' GROUP BY hour WITH ROLLUP) as crossdata
ORDER BY FIELD (hour,'8:00am','9:00am','10:00am','11:00am','12:00pm','1:00pm','2:00pm','3:00pm','4:00pm','5:00pm','6:00pm','7:00pm','8:00pm','9:00pm','10:00pm','11:00pm')
This is ultimately what I want the output to look like:
hour location1 location2 location3 location4 totals
8am 4 3 2 1 10
9am 1 2 2 1 6
10am 2 3 2 3 10
totals 7 8 6 5 26
How can I achieve this?
For what it's worth, this is not a crosstab query. You aren't pivoting rows to columns.
I tried this query and got the result you want:
SELECT IFNULL(hour, 'Total') AS hour,
SUM(location1) AS location1,
SUM(location2) AS location2,
SUM(location3) AS location3,
SUM(location4) AS location4,
SUM(location1)+SUM(location2)+SUM(location3)+SUM(location4) AS totals
FROM counts
WHERE ay = 'AY1617'
GROUP BY hour WITH ROLLUP;
You should really use the TIME data type instead of strings for the hour. Then it just sorts correctly.
+----------+-----------+-----------+-----------+-----------+--------+
| hourt | location1 | location2 | location3 | location4 | totals |
+----------+-----------+-----------+-----------+-----------+--------+
| 08:00:00 | 4 | 3 | 2 | 1 | 10 |
| 09:00:00 | 1 | 2 | 2 | 1 | 6 |
| 10:00:00 | 2 | 3 | 2 | 3 | 10 |
| Total | 7 | 8 | 6 | 5 | 26 |
+----------+-----------+-----------+-----------+-----------+--------+
I am looking for a solution to SELECT (or otherwise derive) the values for Column C (minimum price for last 3 days only, not for the whole column).
----------------------------------------
Date | Unit_ | Low_3_days |
| price | |
----------------------------------------
2015-01-01 | 15 | should be: 15 |
2015-01-02 | 17 | should be: 15 |
2015-01-03 | 21 | should be: 15 |
2015-01-04 | 18 | should be: 17 |
2015-01-05 | 12 | should be: 12 |
2015-01-06 | 14 | should be: 12 |
2015-01-07 | 16 | should be: 12 |
----------------------------------------
My thought revolves around the following, but yielding an error:
select S.Date,Unit_price,
(SELECT min(LOW_3_days)
FROM table
where S.DATE BETWEEN S.DATE-1
and S.DATE-3)
AS min_price_3_days
FROM table AS S
What is the correct query to get this to work? Database used MySQL.
You are pretty close. When working with correlated subqueries, always use table aliases to be absolutely clear about where the columns are coming from:
select S.Date, Unit_price,
(SELECT min(s2.Unit_Price)
FROM table s2
WHERE s2.DATE BETWEEN s.DATE - interval 3 day and
s.DATE - interval 1 day
) as min_price_3_days
FROM table S;
I have payment table info like this
ID Costumer | start_pay | Payment
1 | 2014-01-01 | 1.500
2 | 2013-12-01 | 900
that information they must pay every month, i want calculating it for range between start_pay to CURDATE
if CURDATE is 2014-03-01 (Y-m-d) the result I want like this
ID Costumer | start_pay | Payment | total_to_pay | month_count
1 | 2014-01-01 | 1.500 | 4.500 | 3
2 | 2013-12-01 | 900 | 3.600 | 4
can i do that with mysql query?
Try
SELECT *,TIMESTAMPDIFF(MONTH, DATE_SUB(start_pay,INTERVAL 1 MONTH), CURDATE()) AS
month_count,Payment * month_count AS total_to_pay FROM TABLE
Note that if the difference is less than a month it will output 0
PERIOD_DIFF is basically made for this type of calculation:
SELECT PERIOD_DIFF(DATE_FORMAT(CURDATE(),'%Y%m'), DATE_FORMAT(start_pay, '%Y%m')) from your table;
I need help with a SQL statement. The goal is to count the amount of alarms of each date. My table looks something like this:
|----DATE----|---COUNTER---|---ALARM_ID---|
|2012-01-01 | 30 | 1 |
|2012-01-01 | 20 | 2 |
|2012-01-01 | 10 | 3 |
|2012-01-02 | 5 | 1 |
|2012-01-02 | 25 | 2 |
|2012-01-02 | 12 | 3 |
|2012-01-03 | 33 | 1 |
|2012-01-03 | 43 | 2 |
|2012-01-03 | 11 | 3 |
And I'm looking for a SQL statement that gives this result:
|----DATE----|---COUNTER---|
|2012-01-01 | 60 |
|2012-01-02 | 42 |
|2012-01-03 | 87 |
I've been working on this SELECT date, SUM(counter) FROM all_stats but all I get is:
|----DATE----|---COUNTER---|
|2012-01-01 | 60 |
Do I have to create a loop to go through all dates and count?
Thanks in advance, Steve-O
SELECT date, SUM(counter)
FROM all_stats
GROUP BY date
Try this instead
SELECT date, SUM(counter) FROM all_stats GROUP BY date;
"GROUP BY date" puts all the individual dates on a separate line and does the sum separately per date.
select date, sum(counter)
from all_stats
group by date
How can I get the number of records over a date interval, including dates with no records?
For example I have the following table:
DATE | INSERTID
2011-12-10 | 1
2011-12-10 | 2
2011-12-12 | 3
2011-12-13 | 4
2011-12-15 | 5
2011-12-15 | 6
and the result to be:
DATE | COUNT(INSERTID)
2011-12-10 | 2
2011-12-11 | 0
2011-12-12 | 1
2011-12-13 | 1
2011-12-14 | 0
2011-12-15 | 2
I believe you're going to want to start by generating your list of days, then left join to your object table, grouping on date and doing a count() on the object table. There's already an answer that covers generating the dates, from the looks of it.