I want to replace substrings in PostgreSQL.
For example string "ABC_dog" , 'dogABCcat', 'dogABC' to 'XYZ_dog', 'dogXYZcat', 'dogXYZ'
I tried:
UPDATE my_table SET name = regexp_replace( name , '.*ABC.*', '.*XYZ.*', 'g')
but it set new names to '.XYZ.'
The simplest solution would be to use the replace() function:
UPDATE my_table SET name = replace(name , 'ABC', 'XYZ');
Keep in mind, though, that this will replace all rows in your table. Unless most rows have the pattern you want to replace, you are better off testing for the offending sub-string first:
UPDATE my_table SET name = replace(name , 'ABC', 'XYZ')
WHERE position('ABC' in name) > 0;
The pattern '.*' matches everything, so '.ABC.' means match everything before the ABC, the ABC and everything after as well, so effectively the whole string.
Change it to be just ABC as that is the bit you want to replace. Also, remove the .* from the replacement.
UPDATE my_table SET name = regexp_replace( name , 'ABC', 'XYZ', 'g')
Related
I'm trying to get rid of some bad characters in our database. The rows I'm working on at the moment start with a bullet and a space. My where clause isn't matching the rows in question, however. How can I get a match? This is what I'm currently trying.
update Skill
set Name = substring(Name, 3, 50)
where Name like char(150) + ' %'
Perhaps you aren't capturing the correct ASCII value. Here's a way with unicode that uses a similar method.
declare #table table ([Name] nvarchar(64))
insert into #table
values
('- some data')
select
UNICODE(left([Name],1)) --this will tell you what VALUE to use in the where clause
,NCHAR(UNICODE(left([Name],1)))
from #table
update #table
set [Name] = substring([Name], 3, 50)
where UNICODE(left([Name],1)) = 45 --use the appropriate UNICODE values here
select * from #table
As stated in the comments you can use ASCII() to get the code for the character you are looking for and then use that code in your update.
UPDATE Skill
set Name = substring(Name, 3, 50)
WHERE LEFT(name,1) = CHAR(149)
I have a VARCHAR(1000) column of prices with dollar signs (e.g. $100) and I have created a new NUMERIC(15,2) column, which I'd like to set equal to the prices in the VARCHAR column.
This is what worked for me in MySQL:
UPDATE product_table
SET cost = REPLACE(REPLACE(price, '$', ''), ',','');
but in PostgreSQL it throws an error:
ERROR: column "cost" is of type numeric but expression is of type character
LINE 2: SET cost = REPLACE(REPLACE(price, '$', ''), ',','');
^
HINT: You will need to rewrite or cast the expression.
I tried to follow the hint and tried some Google searches for examples, but my small brain hasn't been able to figure it out.
In PostgreSQL you can do this in one swoop, rather than replacing '$' and ',' s in separate calls:
UPDATE product_table
SET cost = regexp_replace(price, '[$,]', '', 'g')::numeric(15,2);
In regexp_replace the pattern [$,] means to replace either of '$' or ',' with the replace string (the empty string '' in this case), and the 'g' flag indicates that all such patterns need to be replaced.
Then you need to cast the resulting string to a numeric(15,2) value.
Simply cast the result of REPLACE with cast .. as numeric.
Try this:
UPDATE product_table
SET cost = CAST(REPLACE(REPLACE(price, '$', ''), ',','') AS NUMERIC);
I wouldn't suggest having this table structure though, because it can lead to anomalies (cost value doesn't reflect the price value).
I want to convert a column of type "character varying" that has integers with commas to a regular integer column.
I want to support numbers from '1' to '10,000,000'.
I've tried to use: to_number(fieldname, '999G999G999'), but it only works if the format matches the exact length of the string.
Is there a way to do this that supports from '1' to '10,000,000'?
select replace(fieldname,',','')::numeric ;
To do it the way you originally attempted, which is not advised:
select to_number( fieldname,
regexp_replace( replace(fieldname,',','G') , '[0-9]' ,'9','g')
);
The inner replace changes commas to G. The outer replace changes numbers to 9. This does not factor in decimal or negative numbers.
You can just strip out the commas with the REPLACE() function:
CREATE TABLE Foo
(
Test NUMERIC
);
insert into Foo VALUES (REPLACE('1,234,567', ',', '')::numeric);
select * from Foo; -- Will show 1234567
You can replace the commas by an empty string as suggested, or you could use to_number with the FM prefix, so the query would look like this:
SELECT to_number(my_column, 'FM99G999G999')
There are things to take note:
When using function REPLACE("fieldName", ',', '') on a table, if there are VIEW using the TABLE, that function will not work properly. You must drop the view to use it.
right now I have a keyword array like:
['key1', 'key2', 'key3'.......] , the keyword can be number or character.
If I want to search in my table (postgres database), and find out all record contain any of keyword in that array, how can I do that?
For example:
I got a table which has a column called name and a column called description
I need find all record that either name or description contains any keywords in that array.
thanks
Maybe this example will be useful:
CREATE TABLE TEST(
FIELD_KEY TEXT);
INSERT INTO TEST VALUES('this is hello');
INSERT INTO TEST VALUES('hello');
INSERT INTO TEST VALUES('this');
INSERT INTO TEST VALUES('other message');
SELECT *
FROM TEST
WHERE FIELD_KEY LIKE ANY (array['%this%', '%hel%']);
This will return:
this is hello
hello
this
Here other example:
SELECT *
FROM TEST
WHERE FIELD_KEY ~* 'this|HEL';
~* is case insensitive, ~ is case sensitive
You can try this example here.
select *
from t
where
array[name] <# my_array
or array[description] <# my_array
Couple the like operator with the any subquery expression:
select *
from t
where name like any (values ('%John%'), ('%Mary%'))
Or the array syntax:
where name like any (array['%John%', '%Mary%'])
I want to search a column and get values where value containts \ .
I tried select * from "Values" where "ValueName" like '\'. But returns no value.
Also tried like "\" and like'\''%' etc. But no results.
See the DB2 Documentation on the LIKE predicate, in particular the parts about escape expressions.
What you want is
select * from Values where ValueName like '\\%' escape '\'
To give an example of usage:
create table backslash_escape_test
(
backslash_escape_test_column varchar(20)
);
insert into backslash_escape_test(backslash_escape_test_column)
values ('foo\');
insert into backslash_escape_test(backslash_escape_test_column)
values ('no slashes here');
insert into backslash_escape_test(backslash_escape_test_column)
values ('foo\bar');
insert into backslash_escape_test(backslash_escape_test_column)
values ('\bar');
select count(*) from backslash_escape_test where
backslash_escape_test_column like '%\\%' escape '\';
returns 3 (all 3 rows with \ in them).
select count(*) from backslash_escape_test where
backslash_escape_test_column like '\\%' escape '\';
returns 1 (the \bar row).
select * from Values where ValueName like '%\\%'
values is a not so good name because it may be confused with the values keyword
Don't escape it. You just need wildcards around it like this:
select count(*)
from escape_test
where test_column like '%\%'
But, suppose you really do need to escape the slash. Here's a simpler, more straightforward answer:
The escape-expression allows you to specify whatever character for escaping that you wish. So why use a character that you're looking for, thus requiring you to escape it? Use any other character instead. I'll use a plus sign as an example, but it could be a backslash, pound-sign, question-mark, anything other than a character you are looking for or one of the wildcard characters (% or _).
select count(*)
from escape_test
where test_column like '%\%' escape '+';
Now you don't have to add anything into your like-pattern.
To hold myself to the same standard of proof that #Michael demonstrated --
create table escape_test
( test_column varchar(20) );
insert into escape_test
(test_column)
values ('foo\'),
('no slashes here'),
('foo\bar'),
('\bar');
select 'test1' trial, count(*) result
from escape_test
where test_column like '%\%'
UNION
select 'test2', count(*)
from escape_test
where test_column like '%\\%' escape '\'
UNION
select 'test3', count(*)
from escape_test
where test_column like '%\%' escape '+'
;
Which returns the same number of rows for each method:
TRIAL RESULT
----- ------
test1 3
test2 3
test3 3