How to show every max value in mysql? - mysql

I've multiple values with different timestamps like the following:
10 01:01:00
20 01:35:00
30 02:10:00
05 02:45:00
12 03:05:00
21 03:30:00
10 04:06:00
40 05:15:00
I don't have a column with which I can group by and find max. I want to get the records with max values like 30,21, and 40. The data is always in this format, like value increasing and then starts from zero again. What query will help me to find these records?
To clarify, it's sorted by the timestamp, and I want to get the timestamps for the local maxima, the rows where the next row has a lesser value:
value tmstmp
----- --------
10 01:01:00
20 01:35:00
30 02:10:00 <-- this one since next value is 5 (< 30).
05 02:45:00
12 03:05:00
21 03:30:00 <-- this one since next value is 10 (< 21).
10 04:06:00
40 05:15:00 <-- this one since next value is 40 (< infinity).

Somehow your question is not clear to me.
Assume that first column name is "value" and second column name is "timestamp".
Select Max(value) from group by timestamp.

This answer might be a bit late, however i think i have found the solution
SELECT * FROM temp t1 WHERE value >
IFNULL(
(SELECT value FROM temp t2
WHERE t2.tmstmp > t1.tmstmp ORDER BY t2.tmstmp ASC limit 1),
-1
)
ORDER BY tmstmp ASC
To clarify:
I find the values where the value is greater than the next value in the row.
To also get the final value I have added an IFNULL around the subquery to make sure the subquery will then return -1
The only problem i see is when the time goes over to the next day, that's why i hope you can have a date appended to it as well.
Hopefully this will still help others

Related

Query a count of most recent records with a specific value

The table I'm trying to query records the outcome of a specific phone call that was made. So each row has a case_id, last_called (date/timestamp), an outcome (SIQdisp1_a), and then a few other pieces of info (batch number, employee number).
Here is the syntax I'm using currently:
SELECT
DATE(last_called), COUNT(SIQdisp1_a), Access.batch_number
FROM
disposition_log
LEFT JOIN
Access ON disposition_log.case_id = Access.identifier
WHERE
SIQdisp1_a = 14
AND case_id NOT LIKE 'test%'
AND batch_number = 171205
GROUP BY DATE(last_called);
So this will count the number of outcomes per day that = 14 (and are in the appropriate batch). What I need to do, is to modify it such that it only counts the outcome if it is the most recent outcome for that case_id. for instance, if a person was called 3 times in one day, and all 3 times the outcome is equal to 14, I only need that to count once. The syntax I have currently would add all 3 instances of a 14 to the final count.
I've tried using
SELECT MAX(DATE(last_called), COUNT(SIQdisp1_a)
but that returns the same results as the original syntax. I feel like I'm missing something basic here. . . any suggestions are appreciated!
Edit (Including Sample Data):
case_id last_called SIQdisp1_a
1002175 2018-02-16 12:42:36 14
1002175 2018-02-16 13:20:11 14
1005695 2018-02-15 12:00:00 14
1003018 2018-02-15 12:00:00 13
1003018 2018-02-15 11:59:00 14
1005974 2018-02-15 14:33:33 14
Sorry that I didn't include sample data the first time around. With this sample data, each row is a call to somebody (case_id), the date/time of the call (last_called) and the outcome of that call (SIQdisp1_a). What I need, is a count of the number of 14's per day, but the 14 must be the most recent entry for that ID. So in the dataset above, the result would be something like:
Date(last_called) COUNT(SIQdisp1_a)
2018-02-16 1
2018-02-15 2
So for 2-16, the count would be 1 because I ONLY want to count the most recent record. If that most recent record is a 14, it gets added to the total. For 2-15, it's a total of 2 because the most recent outcome for cases 1005974 and 1005695 is 14. Case 1003018 should not be counted because even though there was a 14 at 11:49, there was a call at 12:00 with an outcome of 13. The syntax I posted at the top counts EVERY instance of 14 it sees, it doesn't look for the most recent. Thank you for all your help!
1 option with a subquery:
select date(last_called), count(case_id) from <table> where (case_id,last_called) in (select case_id, max(last_called) from <table> group by case_id,date(last_called)) and SIQdisp1_a=14 group by date(last_called);

How to reliably count preceding rows in MySQL?

I would like to know how to count preceding number of rows of a given row, in a given order by clause, in MySQL.
Also the rows may be inserted randomly, so auto_increment is unreliable.
MyAgenda - List
ID FROM TO
32 2017-09-26 12:35:00 2017-09-26 13:35:00
33 2017-10-10 12:35:00 2017-10-10 13:35:00
32 2017-10-17 12:35:00 2017-10-17 13:35:00
32 2017-10-24 12:35:00 2017-10-24 13:35:00
Like in this case, The rows are sorted by the "From" column, but apparently row 34 is inserted before row 36, but after sorting 36 is above 34, and if another row 37 is inserted it maybe above or below any row, or even at the top. So how can I reliably count the preceding number of rows above a given row, in a given order by clause?
Tried the subquery method but it is O(n^2) and will be painfully slow when the number of rows is large.
This counts records before record #36:
select count(*)
from mytable
where from_date < (select from_date from mytable where id = 36);
First I would suggest not to sort by one column only
try this
ORDER BY From, ID
about your question, not sure if i understood the question correctly but in that case this script may help
SELECT COUNT(*)
FROM your_table
WHERE From > #From
ORDER BY From, ID

Spotfire intersect first 'n' periods

Is there a way to use an Over and Intersect function to get the average sales for the first 3 periods (not always consecutive months, sometimes a month is skipped) for each Employee?
For example:
EmpID 1 is 71.67 ((80 + 60 + 75)/3) despite skipping "3/1/2007"
EmpID 3 is 250 ((350 + 250 + 150)/3).
I'm not sure how EmpID 2 would work because there are just two data points.
I've used a work-around by calculated column using DenseRank over Date, "asc", EmpID and then used another Boolean calculated column where DenseRank column name is <= 3, then used Over functions over the Boolean=TRUE column but I want to figure the correct way to do this.
There are Last 'n' Period functions but I haven't seen anything resembling a First 'n' Period function.
EmpID Date Sales
1 1/1/2007 80
1 2/1/2007 60
1 4/1/2007 75
1 5/1/2007 30
1 9/1/2007 100
2 2/1/2007 200
2 3/1/2007 100
3 12/1/2006 350
3 1/1/2007 250
3 3/1/2007 150
3 4/1/2007 275
3 8/1/2007 375
3 9/1/2007 475
3 10/1/2007 300
3 12/1/2007 200
I suppose the solution depends on where you want this data represented, but here is one example
If((Rank([Date],"asc",[EmpID])<=3) and (Max(Rank([Date],"asc",[EmpID])) OVER ([EmpID])>=3),Avg([Sales]) over ([EmpID]))
You can insert this as a calculated column and it will give you what you want (assuming your data is sorted by date when imported).
You may want to see the row numbering, and in that case insert this as a calculated column as well and name it RN
Rank([Date],"asc",[EmpID])
Explanation
Rank([Date],"asc",[EmpID])
This part of the function is basically applying a row number (labeled as RN in the results below) to each EmpID grouping.
Rank([Date],"asc",[EmpID])<=3
This is how we are taking the top 3 rows regardless if Months are skipped. If your data isn't sorted, we'd have to create one additional calculated column but the same logic applies.
(Max(Rank([Date],"asc",[EmpID])) OVER ([EmpID])>=3)
This is where we are basically ignoring EmpID = 2, or any EmpID who doesn't have at least 3 rows. Removing this would give you the average (dynamically) for each EmpID based on their first 1, 2, or 3 months respectively.
Avg([Sales]) over ([EmpID])
Now that our data is limited to the rows we care about, just take the average for each EmpID.
#Chris- Here is the solution I came up with
Step 1: Inserted a calculated column 'rank' with the expression below
DenseRank([Date],"asc",[EmpID])
Step 2: Created a cross table visualization from the data table and limited data with the expression below

MySQL GROUP BY DateTime with Aggregate Function [duplicate]

This question already has answers here:
SQL select only rows with max value on a column [duplicate]
(27 answers)
Closed 7 years ago.
I seem to remember this working as expected in Oracle, but I can't figure out how to get it right in MySQL.
Here is my query:
SELECT DateTimeStamp, MAX(Value) FROM t1
GROUP BY YEAR(DateTimeStamp), MONTH(DateTimeStamp), DAY(DateTimeStamp);
Running this produces results like:
DateTimeStamp Value
2015-09-09 00:00:29 100
2015-09-10 00:00:05 58
2015-09-11 00:00:57 62
2015-09-12 00:00:49 69
2015-09-13 00:00:43 97
But I was expecting it to look like this, where the DateTimeStamps match up with the values:
DateTimeStamp Value
2015-09-09 03:28:29 100
2015-09-10 03:29:05 58
2015-09-11 03:31:57 62
2015-09-12 03:30:49 69
2015-09-13 03:28:43 97
The correct maximum values are being selected, but the matching DateTimeStamps for those maximum values are not. Instead, it looks like the first DateTimeStamp value for each day is being selected. How can I change my query to display the matching DateTimeStamps?
If all you need is to strip the time section, you need to use the date function:
SELECT date(DateTimeStamp) AS DateTimeStamp, MAX(Value) AS MaxValue
FROM t1
GROUP BY date(DateTimeStamp);
Note: Grouping by something usually make sense when you select it. There is no point to group by YEAR(DateTimeStamp), MONTH(DateTimeStamp), DAY(DateTimeStamp) if all you need is the maximum value per each day.

What would be the best practice to store multiple 2 digit dataset in MySql server

Let say i want to store several dataset ie
78 94 33 22 14 55 18 10 11
44 59 69 79 39 49 29 19 39
And later on i would like to be able run queries that will determine the frequency of certain number. What would be the best way to this? What would be table structure to make a fast query.
Please be specific as you can be.
To get the counts, you can run a query such as:
SELECT value, COUNT(*) from table_of_values GROUP BY value
Placing an index on the single integer value column is pretty much all you can do to speed that up.
You could of course also just keep a table with every two-digit value and a count. You will have to pre-fill the table with zero counts for every value.
Then increment the count instead of inserting:
UPDATE table_of_values SET count = count + 1 WHERE value = (whatever)