extracting data from mysql text field and ordering by it - Possible? - mysql

Let's say I have the following rows:
id data (TEXT)
1 abc"100"dfg
2 abc"200"dfg
3 abc"150"dfg
Would it be possible to order the results by the number in quotes (abc"X"dfg) and return the number?

If the numeric fields are always in the same place you could write
ORDER BY 0 + SUBSTRING(data, 5, 3)
or if they are always bound by the only double quotes in the string you could write
ORDER BY 0 + SUBSTRING_INDEX(SUBSTRING_INDEX(data, '"', -2), '"', 1)
Although the substrings are numeric they are still string values and MySQL will sort them lexically. For a numeric sort they must be forced to numeric values by adding zero.

SELECT *,SUBSTRING(`data`,4,3) AS num FROM table ORDER BY num ASC

Related

How to check if a string in one field exist in every element of a comma separated field

I have a table which contains two fields. The first is name of type string. The second contains one or more strings separated by comma (but it can contain a single string with no commas at all)
I want to construct a query to know if the string in the name field does not exist in every comma separated strings in the names field.
Example 1:
---------------------------------------------------------
name names
---------------------------------------------------------
myname xmyname,myname,mynamey
All the comma separated strings contain the word myname. So the query shoudl not return this row.
But, Example 2:
---------------------------------------------------------
name names
---------------------------------------------------------
myname x,myname,mynamey
Should be returned. Because x does not contain myname.
The condition is that, if the string in the field name does not exists in each of the comma separated strings in the names field, then return the row.
This is not correct as this query will not return true in example 2 (which contains x which does not contain myname).
IMPORTANT NOTE:
1) There is not limit of how many commas there. It can be 0 commas or more. How to deal with this?
2) The strings are variables. It is not always the case that the string is myname. Each row contains a different string in the name field.
Try this regular expression:
where not concat(names, ',') regexp replace('^([^,]*{n}[^,]*,)*$', '{n}', name)
db-fiddle demo
How to read the pattern:
The inner pattern [^,]*{n}[^,]*, means
Any non comma character [^,] repeated any number of times (* means no times or multiple times).
followed by the value of the column name ({n} is a placeholder and will be replaced with the actual value using the replace() function)
followed by any non comma character [^,] repeated any number of times
followed by a comma
The outer pattern ^({inner_pattern})*$ means
Start of the string (^)
followed by the inner pattern repeated any number of times
followed by end of string ($)
To make this work, a comma is appended to the names column (concat(names, ',')), so that every element in the string ends with a comma.
The pattern will ensure, that any element in the comma separated string contains the value of the name column. Since you want the opposite result, we use where not ...
Assuming "myname" does not appear twice between two commas, you can count the commas and "myname"s:
where (length(names) - length(replace(names, ','))) >=
length(names) - length(replace(names, 'myname', '12345'))
This answer started off giving an incorrect REGEXP solution. But the best thing to do here would be to fix your data model, such that each name in the names column is actually on a separate row:
name | names
myname | xmyname
myname | myname
myname | mynamey
somename | x
somename | myname
somename | mynamey
Now we can do a simple aggregation query to answer your question:
SELECT name
FROM yourTable
GROUP BY name
HAVING COUNT(CASE WHEN names NOT LIKE CONCAT('%', name, '%') THEN 1 END) > 0;
Demo
You can approach this using the following SQL query
SELECT
name, names
FROM
`tablename`
WHERE
(LENGTH(names) - LENGTH(REPLACE(names, ',', '')) + 1)
=
ROUND (
(
LENGTH(names)
- LENGTH( REPLACE ( names, name, "") )
)/ LENGTH(name)
);
Explanation:-
This Will give you how many words are separated with ,
(LENGTH(names) - LENGTH(REPLACE(names, ',', '')) + 1) -
Following is matching the name in each row and returning how many times it found
ROUND (
(
LENGTH(names)
- LENGTH( REPLACE ( names, name, "") )
) / LENGTH(name)
)
DEMO

MySQL: How can I return the array length of concatenated data stored in a column with MySQL?

I have data stored in a column called supervisors_id in a table. The structure of data in this column is like this: 12, 44, 55, 32, 85, 75, 45. So I want to fetch the total number of ID's in that supervisors_id column in a row. My expected result, for instance in the above example should be 7. How can I do that with a MySQL query ?
You can count the commas by comparing the length of the string to the length of the string with commas replaced by the empty string.
Somewhat like:
SELECT length(supervisors_id) - length(replace(supervisors_id, ',', '')) + 1
FROM elbat;
If there are also empty strings in the column you might need to add some more logic, that checks for that and returns 0 instead of 1 in that case. For example by using a CASE:
SELECT CASE
WHEN supervisors_id <> '' THEN
length(supervisors_id) - length(replace(supervisors_id, ',', '')) + 1
ELSE
0
END
FROM elbat;
But your design is not the best. Instead of a comma delimited list, there should be a linking table.

How to perform order by on column by splitting the column String?

I am using MySql and I have a table with the column in the form of
first/first1/first2/first3
and
second/second1/second2/second3
I want to perform ordering on the column ignoring the first value of every column before '/'.
i.e. perform ordering on
first1/first2/first3
and
second1/second2/second3
In simple words, I want to perform orderby from first value after '/'.
Any help will be appreciated. Thanks!
Try this one as a sorting criterion:
order by substr(col, instr(col, '/') + 1)
Explanation: The expression extracts the potion after the first occurrence of /. A refined version would cater for values without the separator char, eg.:
order by substr(col, coalesce(instr(col, '/'), 0) + 1)
SELECT .....
FROM ....
ORDER BY SUBSTRING(column FROM INSTR(column, '/') + 1)

query to remove all characters after last comma in string

i have a mysql table with this sort of data
TACOMA, Washington, 98477
Now i have thousands of such rows. I want the data to be manipulated in such a manner that it appears like:
TACOMA, Washington
Is it possible though mysql or do i have to manually do it.
You can use :
SELECT SUBSTRING_INDEX('TACOMA, Washington, 98477', ',', 2)
You can read more here.
And the update statement :
UPDATE my_table
SET my_col = SUBSTRING_INDEX(my_col, ',', 2)
Where you need to replace my_table with your table name and my_col with the column you need to be updated.
Possibly this way. Count the number of commas (by checking the length against the length with all the commas removed) and then use SUBSTRING_INDEX to get the string up to the number of commas:-
SELECT SUBSTRING_INDEX(col, ',', LENGTH(col) - LENGTH(REPLACE(col, ',', '')))
FROM SomeTable
substring_index(col, ',',-1)
will give the string from last index of comma to end of string
replace(col,concat(',',substring_index(col, ',',-1)),'')

mysql remove last characters is character if its number

From select statement, in a filed I want to remove last characters is character if its number. Is there string function available in MySQL?
for these two SQL I want
test
as output
select 'test1';
select 'test';
Another way is to use REGEXP,
SET #val = 'test12';
SELECT CONCAT(LEFT(#val, CHAR_LENGTH(#val) - 1),
IF(RIGHT(#val, 1) REGEXP '[0-9]' = 0, RIGHT(#val, 1), ''))
SQLFiddle Demo
SQLFiddle Demo (another example)
To remove the last character if it's numeric, one way to do this without using a regular expression is with LEFT, RIGHT and LENGTH :
select if( right(yourfield,1) = 0 && right(yourfield,1) != '0',
yourfield,
left(yourfield, length(yourfield) - 1))
from yourtable;
To replace all trailing numeric values, you can use REVERSE:
select if( cast(reverse(yourfield) as signed) = 0 && right(yourfield,1) != '0',
yourfield,
left(yourfield, length(yourfield) - length((reverse(yourfield) + 0))))
from yourtable;
SQL Fiddle Demo
When casting fields as integers/signed in MySQL, it will cast all the numeric characters up to the first non-numeric character -- thus making the REVERSE work. If the last character is not numeric, it results in 0.
Using the IF check above, if the last character isn't numeric, then it prints the original value, else it prints all but the last character.
here is a pointer:
use a union between two queries.
in the first - either use REGEX, or grab the substr of the field where another substr for the last char is a number,
then union the text field where the substr of the last char is not a number.
You might want to use Regular Expressions inside MySQL. This package might help you https://launchpad.net/mysql-udf-regexp. However, I do not recommend to do it inside MySQL statement as it might be slow. You would better to do it after grabbing the value inside your programming language.