How to update a text field with broken JSON literals in PostgreSQL? - sql

I have a lot of character varying records in this format: {'address': 'New Mexico'}.
I would like to update all those columns to have it like this: New Mexico.
I've been investigating how to do it, and it could be with regexp, but I don't know how to make for all columns in a table, and I never used regex in PostgreSQL before.
I have an idea that is something like this:
SET location = regexp_replace(field, 'match pattern', 'replace string', 'g')

Valid JSON literals require double-quotes where your sample displays single quotes. Maybe you can fix that upstream?
To repair (assuming there are no other, unrelated single-quotes involved):
UPDATE web_scraping.iws_informacion_web_scraping
SET iws_localizacion = replace(iws_localizacion, '''', '"')::json ->> 'address'
WHERE iws_id = 3678
AND iws_localizacion IS DISTINCT FROM replace(iws_localizacion, '''', '"')::json ->> 'address';
The 2nd WHERE clause prevents updates to rows that wouldn't change. See:
How do I (or can I) SELECT DISTINCT on multiple columns?
Optional if such cases can be excluded.

Related

Filter centered column SQL Oracle

I try to create a query from an Oracle DB.
that is, SELECT FROM and WHERE.
the column "ORG" is centered and always has 4 letters. I would like to filter that on one specific Item/ value.
I already have WHERE ORG = 'HHAH'
or with SBSTRG (ORG ...:
somehow nothing works.
Does somebody has any idea?
I have values of ' HHAH ' instead of 'HHAH' in the column. There are blanks befor and after the value
You could remove the leading and trailing spaces with the trim() function:
WHERE TRIM(ORG) = 'HHAH'
Using a function on the column value will prevent any index on that column being used (as will like with a leading wildcard); unless you add a function-based index for the trimmed value there isn't much you can do about that.
Do you need the LIKE operator:
WHERE ORG LIKE '%HHAH%'
or
WHERE ORG LIKE '%' || 'HHAH' || '%'
to search for values conatining 'HHAH'?
I would recommend fixing the data:
update t
set org = trim(org);
I see no reason to be storing spaces in the name of an org. If you need spaces for reporting purposes, put them there.

Match Character Whether or Not It Exists in Like Statement

I need a like expression that will match a character whether or not it exists. It needs to match the following values:
..."value": "123456"...
..."value": "123456"...
"...value":"123456"...
This like statement will almost work: LIKE '%value":%"123456"%'
But there are values like this one that would also match, but I don't want returned:
..."value":"99999", "other":"123456"...
A regex expression to do what I'm looking to do is 'value": *?"123456"'. I need to do this in SQL Server 2008 and I don't believe there is good regex support in that version. How can I match using a like statement?
Remove the whitespace in your compare with REPLACE():
WHERE REPLACE(column,' ','') LIKE '%"value":"123456"%'
May need a double replace for tabs:
REPLACE(REPLACE(column,' ',''),' ','')
I don't think you can with the like operator. You could exclude ones you could match, like if you want to make sure it just doesn't contain other:
[field] LIKE '%value":%"123456"%` AND [field] NOT LIKE '%"other"%'
Otherwise I think you'd have to do some processing on the string. You could write a UDF to take the string and parse it to find the value for 'value' and compare based on that:
dbo.fn_GetValue([field], 'value') = '123456'
The function could find the index of '"' + #name + '"', find the next index of a quote, and the one after that, then get the string between those two quotes and return it.

Sqlite - How to remove substring in a field using wildcards

I would like to remove all occurrences of a certain string pattern across all fields in a table.
For example, find all occurrences of the pattern "<XY>*<Xy>" where * represents any possible configuration of characters. I want to remove just those substrings and leave the remainder of the string intact.
This is an example of what I would like to use as my SQL command, but of course this doesn't work:
UPDATE Table SET Field = replace(Field, '<XY>*<Xy>', '');
What is the solution?
Here is an option which attempts to splice around the <XY>...</XY> tags:
UPDATE yourTable
SET Field = SUBSTR(Field, 1, INSTR(Field, '<XY>') - 1) ||
SUBSTR(Field, INSTR(Field, '</XY>') + 5)
WHERE Field LIKE '%<XY>%</XY>%'
It updates fields containing this pattern with the concatenation of everything coming before the first <XY> and everything coming after the second </XY>.
Note that I used <XY>...</XY> rather than what you had originally, because INSTR() is not case sensitive, and both tags would appear as being the same thing.
Demo
The demo is for MySQL but the sytnax is almost identical to SQLite.

SQlite query to update column and replace a value

I want to update a column that contains a string like 12,43,433 I want to only replace 43 with another number say 54 so that the column value becomes 12,54,433.
How can I do that??
You can use REPLACE() function like this:
UPDATE YourTable a
SET a.StringColumn = REPLACE(a.StringColumn,',43,',',54,')
WHERE a.StringColumn like '%,43,%'
Storing lists as strings is a very bad idea. SQL has a great data structure for storing lists. It is called a table, not a string. The proper way to store lists is to use a junction table.
Sometimes we are stuck with other people's really bad design decisions. If so, you can do:
update t
set col = trim(replace(',' || col || ',', ',43,', ',54,'), ',')
where ',' || col || ',' like '%,43,%';
Notes:
This works regardless of where the "43" appears in the string (including at the beginning and end).
This maintains the format of the string with no commas at the beginning and end.
This only attempts to update rows that have the particular elements in the list.
Use of such a query should really be a stopgap while you figure out how to fix the data structure.

MySQL match existence of a term amongst comma seperated values using REGEXP

I have a MySQL select statement dilemma that has thrown me off course a little. In a certain column I have a category term. This term could look something like 'category' or it could contain multiple CSV's like this: 'category, bank special'.
I need to retrieve all rows containing the term 'bank special' in the comma separated value. Currently I am using the following SQL statement:
SELECT * FROM tblnecklaces WHERE nsubcat REGEXP 'bank special';
Now this works OK, but if I had the category as follows: 'diamond special' for example then the row is still retrieved because the term 'special' in my column seems to be matching up to the term 'bank special' in my REGEXP statement.
How would I go abut checking for the existence of the whole phrase 'bank special' only and not partially matching the words?
Many thanks for your time and help
The simplest solution is to use the LIKE clause (% is wildcard):
SELECT * FROM tblnecklaces WHERE nsubcat LIKE '%bank special%';
Note that LIKE is also a lot faster than REGEXP.
You can prefix the column with comma's, and compare it to the bank special:
SELECT *
FROM tblnecklaces
WHERE ',' + replace(nsubcat,', ','') + ',' LIKE ',bank special,'
I put in a replace to remove optional space after a comma, because your example has one.
Not tested but this RegExp should work (LIKE works too but will match items that starts or ends with the same phrase):
SELECT * FROM tblnecklaces WHERE nsubcat REGEXP '(^|, )bank special($|,)';