SQL find in other field data and update another field - mysql

I have troubles with doing such sql query for mysql db:
I need to update field A in my db, but also i have B field, which contains much data, for example:
ASIAN HORSE 70з рус 600A (261x175x220)
or
Бэрен polar 55/59з (555112) 480A (242x175x190)
i must fetch 70з and set it in field A, and 55/59з same (but for another record).
But how can i search in B field something what end's with з but is word (not all data as % before з)
I know, that it could sound like homework... but i real don't know ho to select only word with some end...

The MySQL function substring_index can be used to select pieces of a string delimited by something. For example this picks out the third "word" from MyColumn:
select substring_index(substring_index(MyColumn, ' ', 3), ' ', -1) from MyTable
(70з is the third "word" in ASIAN HORSE 70з рус 600A (261x175x220).)
Update If instead of the third word you are looking for the "word" that ends with 'з', you can use:
select substring_index(substring_index(MyColumn, 'з', 1), ' ', -1) from MyTable
This will consider 'з' as the delimiter though, and removes it from the result. You can add it back with concat:
select concat(substring_index(substring_index(MyColumn, 'з', 1), ' ', -1), 'з') from MyTable

If you are trying to parse the field so the third value always goes into a particular field, then you have a hard problem and probably want to create a user-defined function.
However, if you just want to see if 70з is present and set another field, then this should work:
update t
set B = '70з'
where A like '% 70з' or A like '% 70з %' or A like '70з %' or A = '70з'
This uses spaces to define the word boundaries and considers whether the string is at the beginning, in the middle, at the end, or the entire value in A.

Related

MySQL; find and replace

In my MySQL database I've some strings like this:
I'm something, Infos S. 12
The pattern I want to search for is: , Infos S., than a number (only digits) and than string end. It's case-insensitive.
How can I search for it and remove it?
I have this I'm something, Infos S. 12 and I want I'm something.
This is what I have so far:
UPDATE my_table SET title_col = REPLACE(title_col, SUBSTRING(title_col, LOCATE(', Infos S. ', title_col), LENGTH(title_col) - LOCATE(')', REVERSE(title_col)) - LOCATE(', Infos S. ', title_col) + 2), '') WHERE title_col LIKE '%(%)%';
How to do the rest?
Edit:
If there's another comma it should get ignored.
Means: I'm, something, Infos S. 12 (note the comma after I'm) should get I'm, something.
You can use regexp to check if the column has the specified pattern and then use substring to update the string with substring upto the ,.
UPDATE my_table
SET title_col = SUBSTRING(title_col,1,locate(', Infos',title_col)-1)
WHERE title_col regexp ', Infos S\\. [0-9]+$'
regexp match is case-insensitive by default. If you want to make it case-sensitive, use regexp binary.
where title_col regexp binary ', Infos S\\. [0-9]+$'

How to search strings with an alternate character?

I have a field where I save strings, like:
"one two-tree"
"one-two-tree"
"one-two tree"
"one two tree"
When I do a SELECT, I want to retrieve strings that have either "-" or " " (space). Example:
When I do:
Select name from table where name="one two tree"
I want it to bring also results where there is either space or -, in this case returning all string exemplified above.
Is there a wildcard for this?
As far as standard SQL, you must use "or", or "like". depending on what exactly you want. EXAMPLE: Select name from table where name like "one?two?tree".
However, mySQL supports a REGEX extension that will give you what you want:
http://dev.mysql.com/doc/refman/5.7/en/pattern-matching.html
One option is to use replace:
select name
from yourtable
where replace(name, '-', ' ') = 'one two tree'
There is, but it is slow: you can use REGEXP:
SELECT name
FROM table
WHERE name REGEXP 'one[- ]two[- ]tree'
or you can use replacements:
SELECT name
FROM table
WHERE REPLACE(name, '-', ' ') = 'one two three'
but your best bet is to make an additional column where you will have a normalised name (with dashes always replaced with spaces, for example) so you can take advantage of indices.
You can use the LIKE condition with '%' (wildcard operator) for this.
e.g.
SELECT name from table_name WHERE name LIKE '%-%' OR name LIKE '% %'
-- will return all names that have `-` or ` `.

SQL count number of words in field

I'd like to make an SQL query where the condition is that column1 contains three or more words. Is there something to do that?
maybe try counting spaces ?
SELECT *
FROM table
WHERE (LENGTH(column1) - LENGTH(replace(column1, ' ', ''))) > 1
and assume words is number of spaces + 1
If you want a condition that a column contains three or more words and you want it to work in a bunch of databases and we assume that words are separated by single spaces, then you can use like:
where column1 like '% % %'
I think David nailed it above. However, as a more complete answer:
LENGTH(RTRIM(LTRIM(REPLACE(column1,' ', ' ')))) - LENGTH(REPLACE(RTRIM(LTRIM(REPLACE(column1, ' ', ' '))), ' ', '')) + 1 AS number_of_words
This will remove double spaces, as well as leading and trailing spaces in your string.
Of course, you may go further by adding replacements for more than 2 spaces in a row...
In Postgres you can use regexp_split_to_array() for this:
select *
from the_table
where array_length(regexp_split_to_array(the_column, '\s+'), 1) >= 3;
This will split the contents of the column the_column into array elements. One ore more whitespace are used as the delimiter. It won't respect "quoted" spaces though. The value 'one "two three" four' will be counted as four words.
The best way to do this, is to NOT do this.
Instead, you should use the application layer to count the words during INSERT and save the word count into its own column.
While I like, and upvoted, some of the answers here, all of them will be very slow and not 100% accurate.
I know people want a simple answer to SELECT the word count, but it just is NOT POSSIBLE with accuracy and speed.
If you want it to be 100% accurate, and very fast, then use this solution.
Steps to solve:
Add a column to your table and index it: ALTER TABLE tablename ADD COLUMN wordcount INT UNSIGNED NULL, ADD INDEX idxtablename_count (wordcount ASC);.
Before doing your INSERT, count the number of words using your application. For example in PHP: $count = str_word_count($somevalue);
During the INSERT, include the value of $count for the column wordcount like insert into tablename (col1, col2, col3, wordcount) values (val1, val2, val3, $count);
Then your select statement becomes super easy, clean, uber-fast, and 100% accurate.
select * from tablename where wordcount >= 3;
Also remember when you are updating any rows that you will need to recount the words for that column.
For "n" or more words
select *
from table
where (length(column)- length(replace(column, " ", "")) + 1) >= n
PS: This would not work if words have multiple spaces between them.
With ClickHouse DB You can use splitByWhitespace() function.
Refer : https://clickhouse.com/docs/en/sql-reference/functions/splitting-merging-functions#splitbywhitespaces
None of the other answers seem to take multiple spaces into account. For example, a lot of people use two spaces between sentences; these space-counters would count an extra word per sentence. "Also, scenarios such as spaces around a hyphen - like that. "
For my purposes, this was far more accurate:
SELECT
LENGTH(REGEXP_REPLACE(myText, '[ \n\t\|\-]{1,}',' ')) -
LENGTH(REGEXP_REPLACE(myText, '[ \n\t\|\-]{1,}', '')) wordCount FROM myTable;
It counts any sets of 1 or more consecutive characters from any of: [space, linefeed, tab, pipe, or hyphen] and counts it as one word.
This can work:
SUM(LENGTH(a) - LENGTH(REPLACE(a, ' ', '')) + 1)
Where a is the string column. It will count the number of spaces, which is 1 less than the number of words.
To handle multiple spaces too, use the method shown here
Declare #s varchar(100)
set #s=' See how many words this has '
set #s=ltrim(rtrim(#s))
while charindex(' ',#s)>0
Begin
set #s=replace(#s,' ',' ')
end
select len(#s)-len(replace(#s,' ',''))+1 as word_count
https://exploresql.com/2018/07/31/how-to-count-number-of-words-in-a-sentence/

Find as close as exact matches in database - which way is better?

I have a situation:
I have a database (MySQL) which contains products and their codes like this
BLACK SUGAR BS 709
HOT SAUCE AX889/9
TOMY 8861
I got an excel spreadsheet which I converted to CSV, this contains prices for the products. Its structure consists in 2 columns, code and price, like this:
BS709 23.00
AX 889 /9 10.89
8861 1.69
I made a script to update the products prices by searching in the database for the respective product code, using a FOREACH and %LIKE% query.
FOREACH row in CSV, search the database using "WHERE product_code LIKE %code%.
This is offcourse a primitive and not so succesfull way of updating the prices, because the codes in CSV are not an exact match (in syntax) of those in the database so if I have two products in the DB containing BS709 (BS70923) in their code I get multiple matches.
Is there a better way of doing this ?
You could trim the columns of spaces and other characters using MySQL replace() before comparing. This will return all exact matches, regardless of any spaces contained.
SELECT * FROM table WHERE REPLACE( product_code, ' ', '' ) LIKE 'code'
Given your examples, I would recommend removing all spaces from both, and then just looking for when the beginning or end of a code matches exactly:
where replace(e.code, ' ', '') like concat(replace(db.code, ' ', ''), '%') or
replace(e.code, ' ', '') like concat('%', replace(db.code, ' ', '')) or
replace(db.code, ' ', '') like concat(replace(e.code, ' ', ''), '%') or
replace(db.code, ' ', '') like concat('%', replace(e.code, ' ', ''));
This may not work for the specific case when one code is a prefix of another.
In any case, if the product codes in a spreadsheet are different from the product codes in the database, I think you have bigger problems. If you cannot really fix the spreadsheets, I would recommend that you manually/semi-automatically create a synonyms table in the database. This would have the Excel product code in one column and the correct product code in the other. Then you can do the lookup just by joining this together.
Yes. That is work. But probably less work than struggling with this problem and getting poor results that have to be repeatedly updated.

mysql: how can i remove the street number from a streetaddress column?

I have a column named streetaddress that contains
<Street Number> <Street Name>
for example:
15 rue Gontier-Patin
4968 Hillcrest Circle
how can i remove the numbers from the beginning of the row purely in sql?
How about something like this - trim off everything up to and including the first space in strings which start with a number
UPDATE mytable
SET addresscol=SUBSTRING(addresscol, LOCATE(' ', addresscol)+1)
WHERE addresscol REGEXP '^[0-9]';
This is based on #Paul Dixon above but is just for returning results without updating the data for things like sorting:
SELECT IF(address REGEXP '^[0-9]', SUBSTRING(address, LOCATE(' ', address)+1), address) AS addrSort FROM table;
MySQL does not have regexp replace functions so it depends on the values in your column. If the string always begins with a number and then a space, you can do it with the SQl query Paul Dixon posted (doh, he was faster than me :D ).
If you need regular expressions to solve it, you have to do it in application code outside the database.
I think this should do the job on the basis that each entry has it's street address seperated from the house number by a space (" ");
UPDATE table
SET streetaddress = MID(streetaddress, LOCATE(' ', streetaddress) + 1);
I've tested this and it works fine.
You can also use the following if you'd like to extract the house number to a new column previous to the update;
UPDATE table
SET housenumber = MID(streetaddress, 1, LOCATE(' ', streetaddress) - 1);