Get max value in MySQL? - mysql

I've following values in my database:
Column1
-----
10
20
30
05
12
21
10
40
As you can see, the value is increasing in the first three rows. It starts again in the fourth row with some value like 5. and then starts again in the 7th row with 10, for example. That is, it lowers and then increases again to some extent. The value starts with different numbers. I want to get the highest of each. i.e. I want to get rows with value 30,21, and 40.
Note that I've only the sorted list, It can be done with some variable in programming language but how to do this in mysql with some query?

I would insert all the values into another table which will have only 2 columns (id AUTOINCREMENT and Val as your values).
And then I would use this select:
SELECT
Val
FROM (
SELECT
T1.id, T1.Val, (Select Val from MyTable T2 where T2.id = T1.id + 1) NextVal
FROM
MyTable T1
)
WHERE
Val > NextVal

Related

How to get the first record of each type in sequence?

Table Data:
ID
Type
1
A
2
A
3
B
4
A
5
A
6
B
7
B
8
A
9
A
10
A
How to get only rows with IDs 1,3,4,6,8, or the first records on type-change by single query?
We were doing this in code using multiple queries and extensive processing especially for large data, is there a way to do this in a single query?
Use LAG() window function to get for every row the previous row's type and compare it to the current type.
Create a flag column that is true if the 2 types are different and use it to filter the table:
WITH cte AS (
SELECT *, type <> LAG(type, 1, '') OVER (ORDER BY id) flag
FROM tablename
)
SELECT * FROM cte WHERE flag;
I assume that the column type does not contain empty values (nulls or
empty strings).
See the demo.

How to get distinct records but on base on first 2 digits only in MySQL

I want to get distinct records (only one field) from a MySQL table, and that field contain only digits.
Example:
00010000
01111100
01112000
01118000
02301201
But distinct records is considered on base on first 2 digits. So in the case above, I need to get back only 3 records:
00010000
01112000
02301201
More over, I would like to trim the rest of the digits, so the actual end result should be:
00
01
02
So distinct and group by will not cut here. Any idea?
Assuming you wanted the least value from among duplicates, you could try:
SELECT t1.col
FROM yourTable t1
INNER JOIN
(
SELECT LEFT(col, 2) AS prefix, MIN(col) AS min_col
FROM yourTable
GROUP BY LEFT(col, 2)
) t2
ON LEFT(t1.col, 2) = t2.prefix AND
t1.col = t2.min_col;
Note: Numbers in MySQL don't start with zeroes, so your requirement (and this answer) only make sense if your column is text.
DISTINCT will work fine with LEFT to give the results you want:
SELECT DISTINCT(LEFT(value, 2)) AS value
FROM data
ORDER BY value
Output
00
01
02
Demo on dbfiddle
If you only want the trimmed value, try this:
SELECT SUBSTRING(yourColumn,1,2) as trimmedval
FROM Table
GROUP BY SUBSTRING(yourColumn,1,2)

What would be the SQL query/command to find length of numeric field from a table?

I want to know how we can find of length of Numeric field in sql. What will be the command / Query so that we can find length of perticular field in table.
E.g.:
For below table:
Column1 Column2
1 1111
2 11
3 44444
4 11
5 111
From above example I want to see Record/fields in column "column2" which has numeric length '2'.
What query should I execute to achieve this?
You can also use the POWER function and < and >= to maintain SARGability
WITH tbl (column1, column2) AS(
SELECT 1, 1111 UNION ALL
SELECT 2, 11 UNION ALL
SELECT 3, 44444 UNION ALL
SELECT 4, 11 UNION ALL
SELECT 5, 111
)
SELECT *
FROM tbl
WHERE
column2 < POWER(10, 2)
AND column2 >= POWER(10, 1)
Use LEN function
select *
from table
where len(column2) = 2
This will not work when you want to include data like '0.2' or similar values
You can't as stated here
Length and digits are both properties of a physical representation of a number in a specific base, i.e. a String.
So you have to convert numeric field to varchar/char first then find the length as follows:
SQL Server:
select *
from table
where len(CONVERT (varchar(10), colunm2 )) = 2
MySQL:
select *
from table
where length(convert(column2,char)) = 2

Populate column with number of substrings in another column

I have two tables "A" and "B". Table "A" has two columns "Body" and "Number." The column "Number" is empty, the purpose is to populate it.
Table A: Body / Number
ABABCDEF /
IJKLMNOP /
QRSTUVWKYZ /
Table "B" only has one column:
Table B: Values
AB
CD
QR
Here is what I am looking for as a result:
ABABCDEF / 3
IJKLMNOP / 0
QRSTUVWKYZ / 1
In other words, I want to create a query that looks up, for each string in the "Body" column, how many times the substrings in the "Values" column appear.
How would you advise me to do that?
Here's the finished query; explanation will follow:
SELECT
Body,
SUM(
CASE WHEN Value IS NULL THEN 0
ELSE (LENGTH(Body) - LENGTH(REPLACE(Body, Value, ''))) / LENGTH(Value)
END
) AS Val
FROM (
SELECT TableA.Body, TableB.Value
FROM TableA
LEFT JOIN TableB ON INSTR(TableA.Body, TableB.Value) > 0
) CharMatch
GROUP BY Body
There's a SQL Fiddle here.
Now for the explanation...
The inner query matches TableA strings with TableB substrings:
SELECT TableA.Body, TableB.Value
FROM TableA
LEFT JOIN TableB ON INSTR(TableA.Body, TableB.Value) > 0
Its results are:
BODY VALUE
-------------------- -----
ABABCDEF AB
ABABCDEF CD
IJKLMNOP
QRSTUVWKYZ QR
If you just count these you'll only get a value of 2 for the ABABCDEF string because it just looks for the existence of the substrings and doesn't take into consideration that AB occurs twice.
MySQL doesn't appear to have an OCCURS type function, so to count the occurrences I used the workaround of comparing the length of the string to its length with the target string removed, divided by the length of the target string. Here's an explanation:
REPLACE('ABABCDEF', 'AB', '') ==> 'CDEF'
LENGTH('ABABCDEF') ==> 8
LENGTH('CDEF') ==> 4
So the length of the string with all AB occurrences removed is 8 - 4, or 4. Divide the 4 by 2 (LENGTH('AB')) to get the number of AB occurrences: 2
String IJKLMNOP will mess this up. It doesn't have any of the target values so there's a divide by zero risk. The CASE inside the SUM protects against this.
You want an update query:
update A
set cnt = (select sum((length(a.body) - length(replace(a.body, b.value, '')) / length(b.value))
from b
)
This uses a little trick for counting the number of occurrence of b.value in a given string. It replaces each occurrence with an empty string and counts the difference in length of the strings. This is divided by the length of the string being replaced.
If you just wanted the number of matches (so the first value would be "2" instead of "3"):
update A
set cnt = (select count(*)
from b
where a.body like concat('%', b.value, '%')
)

mysql rows 16-21

If I have a table: ID, num,varchar
where ID is an integer, either 1,2 or 3.
then num is a number, counting from 1 to 100.
varchar is just some text.
So in total we have 300 rows, in no particular ordering in this table.
What query can I use to get the rows with ID=2 and num from 16-21 out of this table?
(resulting in 6 rows total)
How about
SELECT * from yourtable where ID = 2 AND num >= 16 AND num <= 21
Or, equivalent using BETWEEN
SELECT * from yourtable where ID = 2 AND num BETWEEN 16 AND 21
Create an index to have faster lookups later (but will slow down your inserts a bit):
CREATE INDEX indexname on yourtable (ID,num);
SELECT * FROM TABLE WHERE ID = 2 AND NUM > 15 AND NUM < 22;
where TABLE is the name of your table. In general, given that you're selecting on columns ID and NUM they should probably be indexed for faster retrieval (ie the database doesn;t have to check every row). Although given your table is small it probably wont make much difference here.
This should do it:
SELECT * FROM table WHERE id = 2 AND num > 15 AND num < 22