Update column2 if column1 is a number - sql-server-2008-r2

I'm trying to update an int column with the values of a nvarchar() column in sql server 2008. How can I update the column if the value is numeric but leave it null if it isn't?

You can use ISNUMERIC() to check if the column containing varchar data for the update consists entirely of numbers:
UPDATE yourTable
SET col = CAST(varcharcol AS INT)
WHERE ISNUMERIC(varcharcol) = 1

Related

Divide a value in JSON using postgreSQL

Im relatively new and would like to redenominate some values in my current database. This means going into my jasonb column in my database, selecting a key value and dividing it by a 1000. I know how to select values but update after I have performed a calculation has failed me. My table name is property_calculation and has two columns as follows: * dynamic_fields is my jasonb column
ID
dynamic_fields
1
{"totalBaseValue": 4198571.230720645844841865113039602874778211116790771484375,"surfaceAreaValue": 18.108285497586717127660449477843940258026123046875,"assessedAnnualValue": 1801819.534798908603936834409607936611000776616631213755681528709828853607177734375}
2
{"totalBaseValue": 7406547.28939837918763178237213651300407946109771728515625,"surfaceAreaValue": 31.94416993248973568597648409195244312286376953125,"assessedAnnualValue": 9121964.022681592442116216621222042691512210677018401838722638785839080810546875}
I would like to update the dynamic_fields.totalBaseValue by dividing it by 1000 and committing it back as the new value. I have tried the following with no success:
update property_calculation
set dynamic_fields = (
select jsonb_agg(case
when jsonb_typeof(elem -> 'totalBaseValue') = 'number'
then jsonb_set(elem, array['totalBaseValue'], to_jsonb((elem ->> 'totalBaseValue')::numeric / 1000))
else elem
end)
from jsonb_array_elements(dynamic_fields::jsonb) elem)::json;
I get the following error:
ERROR: cannot extract elements from an object
SQL state: 22023
My json column has no zero string or null values.
Move the jsonb_typeof() check into the where clause:
update property_calculation
set dynamic_fields =
jsonb_set(
dynamic_fields,
'{totalBaseValue}',
to_jsonb((dynamic_fields->>'totalBaseValue')::numeric / 1000)
)
where jsonb_typeof(dynamic_fields->'totalBaseValue') = 'number';
db<>fiddle here

Fetch rows from postgres table which contains a specific id in jsonb[] column

I have a details table with adeet column defined as jsonb[]
a sample value stored in adeet column is as below image
Sample data stored in DB :
I want to return the rows which satisfies id=26088 i.e row 1 and 3
I have tried array operations and json operations but it does'nt work as required. Any pointers
Obviously the type of the column adeet is not of type JSON/JSONB, but maybe VARCHAR and we should fix the format so as to convert into a JSONB type. I used replace() and r/ltrim() funcitons for this conversion, and preferred to derive an array in order to use jsonb_array_elements() function :
WITH t(jobid,adeet) AS
(
SELECT jobid, replace(replace(replace(adeet,'\',''),'"{','{'),'}"','}')
FROM tab
), t2 AS
(
SELECT jobid, ('['||rtrim(ltrim(adeet,'{'), '}')||']')::jsonb as adeet
FROM t
)
SELECT t.*
FROM t2 t
CROSS JOIN jsonb_array_elements(adeet) j
WHERE (j.value ->> 'id')::int = 26088
Demo
You want to combine JSONB's <# operator with the generic-array ANY construct.
select * from foobar where '{"id":26088}' <# ANY (adeet);

Convert rows to columns in SQL Server table

My table has the below sample data:
DECLARE #FHTable table (PK_ID int,FK_ID int,P_ID int, T_ID int, A_day int,A_hour TIME,D_day int,D_hour time)
INSERT INTO #FHtable VALUES (129,194,252,1005322,NULL,NULL,1,'02:30:00.0000000')
INSERT INTO #FHtable VALUES (130,194,311,1000891,3,'04:30:00.0000000',null,null)
INSERT INTO #FHtable VALUES (131,194,311,1000129,NULL,NULL,4,'03:30:00.0000000')
INSERT INTO #FHtable VALUES (132,194,252,1000025,6,'03:00:00.0000000',null,null)
SELECT * FROM #FHtable
My final result Should be of the below table:
DECLARE #FinalResultTable TABLE (FK_ID int,P_IDFrom int,P_IDTO INT, T_IDFrom int,T_IDTo INT, A_day int,A_hour TIME,D_day int,D_hour time)
INSERT INTO #FinalResultTable VALUES (194,252,311,1005322,1000891,3,'04:30:00.0000000',1,'02:30:00.0000000')
INSERT INTO #FinalResultTable VALUES (194,311,252,1000129,1000025,6,'03:00:00.0000000',4,'03:30:00.0000000')
select * from #FinalResultTable
The logic is there will be 4 rows for each FK_ID. The first and the second row is a source to destination and the 3rd and 4th row is again a source to destination.
Can you please help
As I pointed out in the comments, it's not very clear what is the logic that joins each arrival with the corresponding departure.
What it's clear to me it's that your title is wrong: you are not talking about converting rows to columns. Instead, you are just grouping 2 by 2 the rows of the table. So, you have 2 approaches, using a GROUP BY or just using a JOIN, it depends on what is exactly your logic.
Here is an example:
select A.FK_ID,
A.PK_ID as P_IDFrom, B.PK_ID as P_IDTO,
A.T_ID as T_IDFrom int, B.T_ID as T_IDTo,
B.A_day, B.A_hour,
A.D_day, A.D_hour
from #FHTable A
join #FHTable B on B.PK_ID+1=A.PK_ID
where A.A_day is null
(this assumes that an arrivals's PK is always +1 w.r.t. its departure).

Update with ISNULL and operation

original query looks like this :
UPDATE reponse_question_finale t1, reponse_question_finale t2 SET
t1.nb_question_repondu = (9-(ISNULL(t1.valeur_question_4)+ISNULL(t1.valeur_question_6)+ISNULL(t1.valeur_question_7)+ISNULL(t1.valeur_question_9))) WHERE t1.APPLICATION = t2.APPLICATION;
I know you cannot update 2 tables in a single query so i tried this :
UPDATE reponse_question_finale t1
SET nb_question_repondu = (9-(COALESCE(t1.valeur_question_4,'')::int+COALESCE(t1.valeur_question_6,'')::int+COALESCE(t1.valeur_question_7)::int+COALESCE(t1.valeur_question_9,'')::int))
WHERE t1.APPLICATION = t1.APPLICATION;
But this query gaves me an error : invalid input syntax for integer: ""
I saw that the Postgres equivalent to MySQL is COALESCE() so i think i'm on the good way here.
I also know you cannot add varchar to varchar so i tried to cast it to integer to do that. I'm not sure if i casted it correctly with parenthesis at the good place and regarding to error maybe i cannot cast to int with coalesce.
Last thing, i can certainly do a co-related sub-select to update my two tables but i'm a little lost at this point.
The output must be an integer matching the number of questions answered to a backup survey.
Any thoughts?
Thanks.
coalesce() returns the first non-null value from the list supplied. So, if the column value is null the expression COALESCE(t1.valeur_question_4,'') returns an empty string and that's why you get the error.
But it seems you want something completely different: you want check if the column is null (or empty) and then subtract a value if it is to count the number of non-null columns.
To return 1 if a value is not null or 0 if it isn't you can use:
(nullif(valeur_question_4, '') is null)::int
nullif returns null if the first value equals the second. The IS NULL condition returns a boolean (something that MySQL doesn't have) and that can be cast to an integer (where false will be cast to 0 and true to 1)
So the whole expression should be:
nb_question_repondu = 9 - (
(nullif(t1.valeur_question_4,'') is null)::int
+ (nullif(t1.valeur_question_6,'') is null)::int
+ (nullif(t1.valeur_question_7,'') is null)::int
+ (nullif(t1.valeur_question_9,'') is null)::int
)
Another option is to unpivot the columns and do a select on them in a sub-select:
update reponse_question_finale
set nb_question_repondu = (select count(*)
from (
values
(valeur_question_4),
(valeur_question_6),
(valeur_question_7),
(valeur_question_9)
) as t(q)
where nullif(trim(q),'') is not null);
Adding more columns to be considered is quite easy then, as you just need to add a single line to the values() clause

PostgreSQL : Update column with same vaue

Following is sample table and data
create table chk_vals (vals text);
insert into chk_vals values ('1|2|4|3|9|8|34|35|38|1|37|1508|1534');
So,How to update column vals by appending integer in 4th position of the existing value(ie. 3 | is used as a seperator) into the last position along with symbol |
as you can see the existsing value if 1|2|4|3|9|8|34|35|38|1|37|1508|1534 and the output should be 1|2|4|3|9|8|34|35|38|1|37|1508|1534|3
Use PostgreSQL's split_part() to splits the field and find the value at position 4
select split_part(vals,'|',4) val from chk_vals
this will return value 3
update chk_vals
set vals=vals||format('|%s',(select split_part(vals,'|',4) val from chk_vals))
Format()