In a MySQL-table I have a VARCHAR-column with different values, which may represent String-, Integer-, Float-, Whatever-Values. These Values are written as a language-specific String into the Database, this means a float-value of 123.45 may be written as a String like "123,45" in german language (using VB.Net...)
As I need average values of float-values wich are in the same group:
How can I cast such a string to a FLOAT within MySQL?
Simply AVG(CONVERT(value, DECIMAL)) won't work (returns 99.00000), conversion to FLOAT is not possible.
Charset is utf8, Collation is utf8_general_ci.
Sample table:
id | value | group
1 | 122,45 | 1
2 | 66,34 | 1
3 | blabla | 2
4 | 109,21 | 1
5 | bababa | 2
Goal: somethig like SELECT AVG(CONVERT(value, DECIMAL)) FROM table WHERE (group=1) should result in 99.333333, not 99.
Any Ideas?
Christoph
PS.: I did not make that database-layout...
You could try
SELECT AVG(CONVERT(
REPLACE(REPLACE(value, '.', ''), ',', '.'),
DECIMAL(10,2)))
FROM `table`
WHERE `group`=1
The string function format(x,d,locale) should do exactly what you want. See https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_format
Related
The MySQL database I am working with has a column with comma separated values similar to -
mysql> select * from performance;
+----+------------------+
| id | maximums |
+----+------------------+
| 1 | 10000RPM, 60KM/h |
| 2 | 5000RPM, 30KM/h |
| 3 | 25mph, 3000RPM |
| 4 | 200KM/h, 2000RPM |
+----+------------------+
4 rows in set (0.00 sec)
I am trying to cast the numbers found in to their own INT columns.
mysql> select maximums,
CASE WHEN maximums like "%mph%" THEN CAST(SUBSTRING_INDEX(maximums, 'mph', 1) AS UNSIGNED) END AS mph_int,
CASE WHEN maximums like "%KM/h%" THEN CAST(SUBSTRING_INDEX(maximums, 'KM/h', 1) AS UNSIGNED) END AS kmh_int,
CASE WHEN maximums like "%RPM%" THEN CAST(SUBSTRING_INDEX(maximums, 'RPM', 1) AS UNSIGNED) END AS rpm_int
from performance;
+------------------+---------+---------+---------+
| maximums | mph_int | kmh_int | rpm_int |
+------------------+---------+---------+---------+
| 10000RPM, 60KM/h | NULL | 10000 | 10000 |
| 5000RPM, 30KM/h | NULL | 5000 | 5000 |
| 25mph, 3000RPM | 25 | NULL | 25 |
| 200KM/h, 2000RPM | NULL | 200 | 200 |
+------------------+---------+---------+---------+
4 rows in set, 4 warnings (0.00 sec)
I expect the output to show me the values as INTs in new columns, however am unsure how to achieve this.
Let's give this a whirl, using the good ol'-fashioned blunt instrument approach. I am guessing that you only need this to work once, to convert an old, poorly-designed schema into something more workable. Given that, I have made no effort at elegance or performance.
(If you are not using this to fix your data schema, you should, because the pain you are experiencing now is only the beginning.)
First, we need to split the maximums value into two pieces and process them separately. The first half is:
SUBSTRING_INDEX(`maximum`, ',', 1)
The second half is similar, but there is a stray space:
TRIM(SUBSTRING_INDEX(`maximum`, ',', -1))
From here on, let's just always trim, in case there is variation in the data. Now we need to see if the first section has 'mph' in it, and if so capture the value as you did in your question (this is essentially like your example but operating on only the first part of the maximum value):
IF(TRIM(SUBSTRING_INDEX(`maximum`, ',', 1)) LIKE '%mph', SUBSTRING_INDEX(TRIM(SUBSTRING_INDEX(`maximum`, ',', 1)), 'mph', 1), NULL)
Let's name that chunk of code "mph test on first half". The mph test on the second half is almost identical, just using -1 as the index. Finally, we need to put the non-null value (if either) into the column using COALESCE. Once we create all six variations of the test, we end up with the following:
SELECT
...
COALESCE([mph test on first half], [mph test on second half]) AS mph_int,
COALESCE([kph test on first half], [kph test on second half]) AS kph_int,
COALESCE([rpm test on first half], [rpm test on second half]) AS rpm_int
WHERE
...
Chances are you don't actually need to formally cast the string of digits into an integer; if you are inserting into a table with columns of those types, MySQL will cast the value for you.
I got a big data (approximately 600,000).
I want the rows with value "word's" will appear.
Special characters will be completely ignored.
TABLE:
| column_value |
| ------------- |
| word's |
| hello |
| world |
QUERY: select * from table where column_value like '%words%'
RESULTS:
| column_value |
| ------------- |
| word's |
I want the rows with special characters will appear and ignore their special characters.
Can you please help me how can we achieve it with fast runtime?
You can use replace to remove the "special" character prior the matching.
SELECT *
FROM table
WHERE replace(column_value, '''', '') LIKE '%words%';
Nest the replace() calls for other characters.
Or you try it with regular expressions.
SELECT *
FROM table
WHERE column_value REGEXP 'w[^a-zA-Z]*o[^a-zA-Z]*r[^a-zA-Z]*d[^a-zA-Z]*s';
[^a-zA-Z]* matches optional characters, that are not a, ..., y and z and not A, ..., Y and Z, so this matches your search word also with any non alphas between the letters.
Or you have a look at the options full text search brings with it. Maybe that can help too.
You must add an index on your column_value.
MySQL doc
I'm working with a MySQL database that contains a substantial amount of data (about 10.000 records). The data in the database is logging of a machine maintenance, one of the fields contains a basic timeline (just steps that are timestamped) explaining all the work done. In this field I'm looking for certain strings that can indicate certain procedures (i.e. ABC123.ABC, abc111.abc, abc001.abc).
I'm looking for matches in this field with pattern matching like such
SELECT * FROM [tablename]
WHERE `work_performed` LIKE '% ______.___ %'
ORDER BY id DESC;`
The regex is very general but I can specify that further myself.
However, since the field which contains the string I'm looking for can be very large (up to 2364763 characters) i want to return the records matching the pattern specified but I also want to return a field that contains just the matched expression so I can confirm it is actually what I'm looking for and can use that string further.
I have found people with the same issue but I cannot reproduce their results.
Something like this might work?:
SELECT *, SUBSTRING(`work_performed`,
patindex('%[0-9][0-9][0-9]%', `work_performed`)-1, 5) as match
FROM [tablename]
WHERE `work_performed`LIKE '% ______.___ %'
I would like to get output that looks somewhat like this:
+----+-------------------------------------------+------------+
| id | work_performed | match |
+----+-------------------------------------------+------------+
| 1 | 2017-02-26|10:59| Arrival: admin1 | ABCD12.adb |
| | 2017-02-26|10:59| diagnosed error ab-0001 | |
| | 2017-02-26|11:02| ran ABCD12.adb | |
| | 2017-02-26|11:03| system back online | |
+----+-------------------------------------------+------------+
| 2 | 2017-02-26|10:59| Arrival: admin34 | abc123.ags |
| | 2017-02-26|10:59| diagnosed error WP1234 | |
| | 2017-02-26|11:02| ran abc123.ags | |
| | 2017-02-26|11:03| system back online | |
+----+-------------------------------------------+------------+
I apologise if I didn't give enough details but I'm an intern at a major company and we have very strict rules about confidentiality.
If there is a need for any additional information I will try to.
EDIT
I have been trying to search for the string I'm looking for with regexp, but I cant get it to work as I want to, here is what I tried:
SELECT * FROM tablename
WHERE `work_performed` regexp '% ([a-z]^3)([0-9]^3).([a-z]^3) %'
ORDER BY id DESC;
The solution using CONCAT, SUBSTR, SUBSTRING_INDEX and LOCATE functions:
SELECT
CONCAT(SUBSTRING_INDEX(SUBSTRING_INDEX(work_performed, '.', 1), ' ', - 1),
'.',
SUBSTR(SUBSTRING_INDEX(work_performed, '.', - 1), 1,
LOCATE(' ', SUBSTRING_INDEX(work_performed, '.', - 1))
)
) m
FROM
tablename
https://dev.mysql.com/doc/refman/5.7/en/string-functions.html
DEMO link
I have a SQL table with the following values:
+---------+----------+
| post_id | path |
+---------+----------+
| 1 | 1/ |
| 2 | 1/2/ |
| 3 | 1/2/3/ |
| 4 | 1/2/3/4/ |
| 5 | 1/2/5/ |
+---------+----------+
How can I create a query that would get the path with the exact number of values separated by slashes?
For example, if I wanted all post_ids where the path is exactly 1/%/%/ (where each % represents a single number), meaning return anything of the form 1/2/3/, 1/2/5/, but not 1/2/3/4/.
Here's one option using regexp:
select *
from yourtable
where path regexp '1/[0-9]/[0-9]/$'
SQL Fiddle Demo
There are several ways to do that:
MySQL LIKE operator.
The LIKE operator provides two wildcard characters, the percentage % ( match any string of zero or more characters), and underscore _ ( match any single character ).
SELECT * FROM `table` WHERE `path` LIKE '1/_/_/'
SELECT * FROM `table` WHERE `path` LIKE '1/%/%/'
MySQL Regular Expressions.
SELECT * FROM `table` WHERE `path` regexp '^1/[0-9]/[0-9]/$'
Hierarchical Data in MySQL
Since this structure involves hierarchical data maybe you should consider to change the table structure to something that represents actual hierarchy. http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/ has an excellent tutorial about the subject.
In a MySQL-table I have a VARCHAR-column with different values, which may represent String-, Integer-, Float-, Whatever-Values. These Values are written as a language-specific String into the Database, this means a float-value of 123.45 may be written as a String like "123,45" in german language (using VB.Net...)
As I need average values of float-values wich are in the same group:
How can I cast such a string to a FLOAT within MySQL?
Simply AVG(CONVERT(value, DECIMAL)) won't work (returns 99.00000), conversion to FLOAT is not possible.
Charset is utf8, Collation is utf8_general_ci.
Sample table:
id | value | group
1 | 122,45 | 1
2 | 66,34 | 1
3 | blabla | 2
4 | 109,21 | 1
5 | bababa | 2
Goal: somethig like SELECT AVG(CONVERT(value, DECIMAL)) FROM table WHERE (group=1) should result in 99.333333, not 99.
Any Ideas?
Christoph
PS.: I did not make that database-layout...
You could try
SELECT AVG(CONVERT(
REPLACE(REPLACE(value, '.', ''), ',', '.'),
DECIMAL(10,2)))
FROM `table`
WHERE `group`=1
The string function format(x,d,locale) should do exactly what you want. See https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_format