I have a table that contains a json type in one row called whole_params, and I would like to change values if json param called exampleParam equals value1 I want to change it to value2
UPDATE table_name t
SET whole_params = json_set(whole_params, '{exampleParam}')::jsonb)
WHERE t.whole_params ->> 'exampleParam' = 'value1';
I wrote something like that but I do not know how to change that 'value1', any ideas?
You just need to use jsonb_set() instead of json_set() with a slight change as
UPDATE table_name t
SET whole_params = jsonb_set(whole_params, '{exampleParam}','"value2"')
WHERE t.whole_params ->> 'exampleParam' = 'value1';
Related
I need help with replacing column value to replace all '%' delimiter with '~'.
Example:
CTP%3A1c5d8384-5980-4bee-88f5-aed7594594ba%7ESV%3ANA%7ECUST%3Anew%7ECSR%3AGREATER+BOSTON+MARKET%7ECSD%3ANORTHEAST+DIVISION%7EZIP%3A02140%7EBFT%3AAll+digital+buyflow%7Cdotcom%7EBPT%3ANA%7EIDV%3ANA%7EMRC%3ANA%7ESIKE%3ANA%7ESIKP%3ANA%7ESIKS%3ANA%7ERAF%3Ano
CTP%3A7ef7b00a-10dc-41e9-8691-0a01463703c9%7ESV%3ANA%7ECUST%3Aexisting%7ECSR%3ABIG+SOUTH+REGION%7ECSD%3ACENTRAL+DIVISION%7EZIP%3A30101%7EBFT%3AAll+digital+buyflow%7Cdotcom%7EBPT%3ANA%7EIDV%3ANA%7EMRC%3ANA%7ESIKE%3ANA%7ESIKP%3ANA%7ESIKS%3ANA%7ERAF%3Ano
CTP%3A9ed9ba57-4227-444a-9385-101bbc0df3bc%7ESV%3ANA%7ECUST%3Anew%7ECSR%3ABIG+SOUTH+REGION%7ECSD%3ACENTRAL+DIVISION%7EZIP%3A30047%7EBFT%3AAll+digital+buyflow%7Cdotcom%7EBPT%3ANA%7EIDV%3ANA%7EMRC%3ANA%7ESIKE%3ANA%7ESIKP%3ANA%7ESIKS%3ANA%7ERAF%3Ano
CTP%3Ae46e7133-340d-41b9-9cdf-2baea14c86b6%7ESV%3ANA%7ECUST%3Aexisting%7ECSR%3ASEATTLE+MARKET%7ECSD%3AWEST+DIVISION%7EZIP%3A98223%7EBFT%3AAddOnChannel%7EBPT%3ANA%7EIDV%3ANA%7EMRC%3ANA%7ESIKE%3ANA%7ESIKP%3ANA%7ESIKS%3ANA%7ERAF%3Ano
Expected Output:
CTP~3A1c5d8384-5980-4bee-88f5-aed7594594ba~7ESV~3ANA~7ECUST~3Anew~7ECSR~3AGREATER+BOSTON+MARKET~7ECSD~3ANORTHEAST+DIVISION~7EZIP~3A02140~7EBFT~3AAll+digital+buyflow~7Cdotcom~7EBPT~3ANA~7EIDV~3ANA~7EMRC~3ANA~7ESIKE~3ANA~7ESIKP~3ANA~7ESIKS~3ANA~7ERAF~3Ano
CTP~3A7ef7b00a-10dc-41e9-8691-0a01463703c9~7ESV~3ANA~7ECUST~3Aexisting~7ECSR~3ABIG+SOUTH+REGION~7ECSD~3ACENTRAL+DIVISION~7EZIP~3A30101~7EBFT~3AAll+digital+buyflow~7Cdotcom~7EBPT~3ANA~7EIDV~3ANA~7EMRC~3ANA~7ESIKE~3ANA~7ESIKP~3ANA~7ESIKS~3ANA~7ERAF~3Ano
CTP~3A9ed9ba57-4227-444a-9385-101bbc0df3bc~7ESV~3ANA~7ECUST~3Anew~7ECSR~3ABIG+SOUTH+REGION~7ECSD~3ACENTRAL+DIVISION~7EZIP~3A30047~7EBFT~3AAll+digital+buyflow~7Cdotcom~7EBPT~3ANA~7EIDV~3ANA~7EMRC~3ANA~7ESIKE~3ANA~7ESIKP~3ANA~7ESIKS~3ANA~7ERAF~3Ano
CTP~3Ae46e7133-340d-41b9-9cdf-2baea14c86b6~7ESV~3ANA~7ECUST~3Aexisting~7ECSR~3ASEATTLE+MARKET~7ECSD~3AWEST+DIVISION~7EZIP~3A98223~7EBFT~3AAddOnChannel~7EBPT~3ANA~7EIDV~3ANA~7EMRC~3ANA~7ESIKE~3ANA~7ESIKP~3ANA~7ESIKS~3ANA~7ERAF~3Ano
I have tried to use OREPLACE but it didn't work.
UPDATE A
SET ORDER_INFO = OREPLACE(ORDER_INFO,'%','~')
WHERE ORDER_INFO NOT LIKE '%~%' AND CTP_SESSION_ID IS NULL;
UPDATE A
SET ORDER_INFO = OREPLACE(ORDER_INFO,'%','~')
WHERE ORDER_INFO NOT LIKE '%~%'
AND CTP_SESSION_ID IS NULL;
I'm trying to implement the behavior of selecting data based on either an array of input, or get all data if array is null or empty.
SELECT * FROM table_name
WHERE
('{}' = $1 OR col = ANY($1))
This will return pq: op ANY/ALL (array) requires array on right side.
If I run
SELECT * FROM table_name
WHERE
(col = ANY($1))
This works just fine and I get the contents I expected.
I can also use array_length but it will request me to assert what type of data is in $1. If I do (array_length($1::string[],1) < 1 OR col = ANY($1)), it seems to always return false on the array_length and go on to the col = ANY($1)
How can I return either JUST the values from $1 OR all if $1 is '{}' or NULL?
Got it:
($1::string[] IS NULL OR event_id = ANY($1))
I am trying to update the jsonb column media, with two keys i.e
default** is of type jsonb and image_set is an array of jsonb.
Is there is solution for single select update statement to update both keys.
test_media table
id | media | name
----+-------------------------------------------------------------------------------------------------------------------------------------------------------+-------
2 | {"default": {"w1": "fff", "w2": "aaa", "w3": "ddd"}, "image_set": [{"w1": "fff", "w2": "aaa", "w3": "ddd"}, {"w1": "bbb", "w2": "rrr", "w3": "vvv"}]} | pooja
Updating image-set
Update test_media
set media = media #- ('{image_set,'||(select pos-1 from test_media, jsonb_array_elements(media->'image_set') with ordinality arr(value, pos) where name='pooja' and value->>'w1'='fff')
|| '}')::text[]
|| jsonb_set(media, '{default}', '{"w1": "bbb", "w2": "rrr", "w3": "vvv"}' )
where name='pooja';
Here, based on delete, I want to update the default and image_set together depends on different condition.default jsonb value is from image_set array. I tried using case statement but it is not working fine. Different conditions of delete are :
When the jsonb value, i want to delete is in default as well as in
image_set, it should delete that value from image set and update the
default with other value from image set.
If not so, it won't update default, just the image_set value will be
deleted.
If the value of array i.e image_set is 1 , then the media='{}' updated
to null json.
Tried two things updating separately, default and image_set.
Update test_media
set media = ( CASE
WHEN jsonb_array_length(media->'image_set')::int > 1
THEN (Select media #- ('{image_set,'||(select pos-1 from test_media , jsonb_array_elements(media->'image_set') with ordinality arr(value, pos) where name='pooja' and value->>'w1'='fff') || '}')::text[])
ELSE media = '{}'
END IF
)
where name='pooja';
Here, i got the error:CASE types boolean and jsonb cannot be matched
Secondly,
update test_media
set media = jsonb_set(media, '{default}', (select from (select CASE WHEN media->'default'->>'w1'='fff' AND jsonb_array_length(media->'image_set')::int >0 THEN (select media->'image_set'->0 from test_media where name='pooja' ) WHEN media->'default'->>'w1'='fff' AND jsonb_array_length(media->'image_set')::int = 0 THEN (select media - 'default' from test_media where name = 'pooja') END) As Sub), True)
where name='pooja';
I would be thankful if i get support for case statement using select update. Hope for a positive response. Thanks.
updating multiple jsonb column
update-multiple-values-in-a-jsonb-data
I have Ticket table that has some columns like this :
ID : int
Body : nvarchar
Type : int
I have many rows where the Body column has value like this :
IPAddress = sometext, ComputerName = sometext , GetID = sometext, CustomerName=sometext-sometext , PharmacyCode = 13162900
I want update all rows' Type column where the Body column has at least five of the following keys:
IPAddress, ComputerName, GetID, CustomerName, PharmacyCode
You could do it with a simple update statement like that
UPDATE Ticket
SET Type = 4
WHERE Body LIKE '%IPAddress%'
and Body LIKE '%ComputerName%'
and Body LIKE '%GetID%'
and Body LIKE '%CustomerName%'
and Body LIKE '%PharmacyCode%'
if you know the 'keys' are always in the same order you could concatenate the LIKE conditions like so
UPDATE Ticket
SET Type = 4
WHERE Body LIKE '%IPAddress%ComputerName%GetID%CustomerName%PharmacyCode%'
If you have the possibility to change the data model it would be much better to explode this key & value column into an own table and link it back to this table as it is done in a proper relational model.
If you could calculate number of key value pair by number of = present in your string you could use this query
Update tblname set col=val where len(colname) - len(replace(colname,'=','')>5
The where part actually gives number of equal signs present in your string.
I have an XML data type column called "tags".
In that, I am storing a collection, like so:
<ArrayOfString>
<string>personal</string>
<string>travel</string>
<string>gadgets</string>
<string>parenting</string>
</ArrayOfString>
I want to select all the rows, that have one of the values that I am looking for: for example, I want to select all rows in the table that have a tag "travel".
I know that this works, if I know the index of the value I am looking for:
select * from posts
where tags.value('(/ArrayOfString/string)[1]', 'nvarchar(1000)') = 'travel'
but this query works only if the tag "travel" is the 2nd item in the nodes. How do I check if a value exists, irrespective of the position it is in?
select *
from tags
where tags.exist('/ArrayOfString/string[. = "travel"]') = 1
Or like this if you want to check against a variable.
declare #Val varchar(10)
set #Val = 'travel'
select *
from tags
where tags.exist('/ArrayOfString/string[. = sql:variable("#Val")]') = 1
You can try something like this:
SELECT
*
FROM
dbo.Posts
WHERE
tags.exist('/ArrayOfString/string/text()[. = "travel"]') = 1
This will list all the rows that have "travel" in one of the strings in your XML