How to flatten results from table-valued function in MySQL? - mysql

I am using MySQL, and I have a function which will accept a col data from a table row, and return a table-valued function. for example, a function like this:
CREATE FUNCTION [dbo].[wordlongerthan4](
#input text
) returns #result table(
pos int,
word varchar,
)
which will return the word longer than 4char and its position.
i want to do a sql something like below
select t.name,wordlongerthan4(t.content) from sometable as t;
on table
------------------------------------------------------------------
| id | name | content |
------------------------------------------------------------------
|1 | my1 | i love something and nothing |
|2 | my2 | It is a sunny day today |
to get the result:
|name | pos | word |
--------------------------------
|my1 |8 |something |
|my1 |22 |nothing |
|my2 |9 |sunny |
|my2 |20 |today |
How could i write the sql?(the function wordlongerthan4 is already there,i only need the sql!)

What you are talking about doing is:
Looping through each record and extracting the content.
Splitting the content by a delimiter (space, in this case).
Measuring the length of each part
Adding the part to an array of successful results it its length < n
(4).
Returning the part, along with the original id and name from the
record it originally came from.
Like ajreal said, this is something that would best be done at the application layer, presumably inside of your php/java/whatever.
There is currently no built-in string explode/split function, but this question here might prove useful: Equivalent of explode() to work with strings in mysql.

You can (ab)use the new JSON_TABLE function in MySQL 8 to do this:
set #input = 'i love something and nothing';
SELECT Value, LENGTH(Value) as Length, LOCATE(Value, #delimited) as pos
FROM
JSON_TABLE(
CONCAT('["', REPLACE(#delimited, ' ', '", "'), '"]'),
"$[*]"
COLUMNS(
Value varchar(50) PATH "$"
)
) data
where LENGTH(Value) > 4;

Related

Remove All Backslash into string in MySQL query

I have this type of string
'160f7a4a-766a-4c23-a155-8bd3f7389f77\', \'63233bfc-b663-4c73-890b-00a48d79c4dc'
In one column and I want like
'160f7a4a-766a-4c23-a155-8bd3f7389f77','63233bfc-b663-4c73-890b-00a48d79c4dc'
This type of result in MySQL
i have to perform query like
SELECT * FROM kapp_staging.kols where `kol_id` in (select REPLACE(json_id,'\'',"'") FROM kapp_staging.news_items
where `id` = '991'))
in where in clause i have subquery and in subquery
i geting
'160f7a4a-766a-4c23-a155-8bd3f7389f77\', \'63233bfc-b663-4c73-890b-00a48d79c4dc'
this type of value
so i need to remove \ from value so my where in query work fine.
i have data like:
Kols table
| id | kol_id | name | data |
|----|---------------------------------------- |---------| ------|
| 1 |160f7a4a-766a-4c23-a155-8bd3f7389f77 | balwant | data |
| 2 |63233bfc-b663-4c73-890b-00a48d79c4dc | vikram | data |
news items
| id | json_id | data |
|----|-----------------------------------------------------------------------------------------|---------|
| 991 | {'\160f7a4a-766a-4c23-a155-8bd3f7389f77\','\160f7a4a-766a-4c23-a155-8bd3f7389f77\'} | data |
I tried many ways but didn't get this response.
Thanks in Advance : )
The backslashes aren't in the data, they're just used to escape the quotes when inserting into the table. So you don't need to remove them.
However, you can't use IN to match values in a comma-delimited list, you need to use FIND_IN_SET(); see Search with comma-separated value mysql
You also need to remove the quotes and curly braces before you can use FIND_IN_SET().
SELECT DISTINCT k.*
FROM kols AS k
JOIN news_items AS n
ON FIND_IN_SET(k.kol_id,
REPLACE(REPLACE(REPLACE(json_id, '{', ''), '}', ''), "'", ''))
DEMO
Things would be much easier if you normalized your data and put the list of IDs into a separate table with one row per ID.

MySQL - VARCHAR to FLOAT [duplicate]

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

Read out last X letters from the right via MYSQL

I have a table with a varchar field that contains a description with variable lenght. I want to read the 4th last letters from the right.
For example if the table contained:
|col1 |
+-----+
|20161512_NL_Luxus_1_DE |
|20161512_NL_Premium_2_DE |
|20161512_NL_SDT_4_DE|
I want a query that will return:
|result|
+------+
|1 |
|2 |
|4 |
Thanks in advance!
SUBSTRING_INDEX seems like it would be a good fit for what you're trying to accomplish:
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(col1, '_', -2), '_', 1);
See the MySQL Docs for more info on usage.
Essentially, the inner call to SUBSTRING_INDEX is finding the second to last _ character and returns everything to the right of it. The outer SUBSTRING_INDEX call is then finding the first _ from this result and returning everything up until that point.

Get path with specific number of values

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.

MySQL: Convert String to Float/Decimal in german language

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