updating for several columns with distinct conditions - sql

I have INSERT statement where values are provided through SELECT from other table. ON CONFLICT I'm updating several columns. I'm just wondering if is possible to SET each column matching unique condition
Now I have solution which work, however it isn't ideal.
Basically something like this would match my desired result..
WITH table_a (
--joining two tables
)
INSERT INTO table_b
SELECT * FROM table_a
ON CONFLICT
ON CONSTRAINT table_b_pkey DO UPDATE
SET column_a = EXCLUDED.column_a
WHERE table_b.column_a < EXCLUDED.column_a
OR
SET column_b = EXCLUDED.column_b
WHERE table_b.column_b < EXCLUDED.column_b

Use CASE, e.g.:
INSERT INTO table_b
SELECT * FROM table_a
ON CONFLICT
ON CONSTRAINT table_b_pkey DO UPDATE
SET
column_a = CASE
WHEN table_b.column_a < EXCLUDED.column_a
THEN EXCLUDED.column_a
ELSE table_b.column_a END,
column_b = CASE
WHEN table_b.column_b < EXCLUDED.column_b
THEN EXCLUDED.column_b
ELSE table_b.column_b END

Related

Moving a cell value to another row based on ID numbers

I am looking to move B to the above row. It can either be placed where the Null value is in Column B or another column can be created. The value of B is linked to value A through an ID. The ID for value B is always X + 2 (the values in the ID column are integers).
I can’t just move the value up because the table I am working with has thousands of rows. It must be linked to the ID’s.
Please let me know if you have any questions. Any assistance is much appreciated. Thank you.
ID
Column A
Column B
X
A
NULL
X+2
NULL
B
Keep in mind I am very new to SQL. Below is what I tried. It created a new column that only contains NULL values.
Select
Column_B
From
Table_Name
Where
Table_Name.ID = Table_Name.ID +2 ) AS Col_B_Value
You can use a conditional subselect for that
UPDATE Table_Name T1
SET Column_B = (Select
Column_B
From
Table_Name
Where
Table_Name.ID = T1.ID +2 )
WHERE Column_B IS NULL
Some databases could have a problem so you can make
UPDATE Table_Name T1
SET Column_B = (Select
T2.Column_B
From
(SELECT ID,Column_B FROM Table_Name) T2
Where
T2.ID = T1.ID +2 )
WHERE Column_B IS NULL
You could just do it with 2 updates statements
UPDATE Table
SET Column B = 'B'
WHERE ID = 'X'
UPDATE Table
SET Column B = NULL
WHERE ID = 'X+2'
If you need to do it in a select statement you could do it with a case statement too
SELECT ID,
Column A,
CASE WHEN ID = X AND Column B = NULL THEN 'B'
ELSE Column B END
FROM Table

How to rewrite this sql query, that updates multiple rows in a single column, WITHOUT using CASE

I am working on a new project and am trying to update multiple rows in a single column. It appears any query using the CASE syntax is throwing an error. I am needing to rewrite this query so that the CASE syntax is not used. Any help here is appreciated, i have:
UPDATE tableA
SET
column_a = CASE WHEN column_a = 'conserve' THEN 'fixed'
WHEN column_a = 'balance' THEN 'mod'
WHEN column_a = 'balance growth' THEN 'mod growth'
WHEN column_a = 'aggressive' THEN 'mod/agressive'
END;
The error I am seeing in our pipleine is:
Caused by: liquibase.exception.DatabaseException: ERROR: syntax at or near "column_a"
I am looking for alternatives to using CASE when updating multiple rows in a single column.
Not sure what a reason to not use CASE (coz imo it's a more useful option), but here's dbfiddle with a couple of alternatives for the UPDATE statement (REPLACE and CTE):
-- replace example
UPDATE tableA
SET
column_a = REPLACE(REPLACE(REPLACE
(column_a, 'conserve', 'fixed'),
'balance', 'moderate'),
'aggressive','moderate/agressive');
-- CTE example
UPDATE tableA
SET
column_a = tmp.tmp_val
FROM (
SELECT 'conserve' as tmp_key, 'fixed' as tmp_val
union select 'balance', 'moderate'
union select 'balance growth', 'moderate growth'
union select 'aggressive', 'moderate/agressive'
) tmp
WHERE tmp.tmp_key = tableA.column_a
;
I would write this query like as follows. It's not pritty but should get the job done.
UPDATE tableA
SET column_a = REPLACE(column_a, 'conserve', 'fixed'),
column_a = REPLACE(column_a, 'balance', 'moderate'),
...

How to update the Top (20) records with using Select Query

How to update the Top (20) records with using Select query?
Table1 (table records are in for loop) has 60 records. At a time, I want to get first 20 records based on table column="TEXT", then update those 20 records with column="TEXT1".
After that, I will pick the next 20 records (21-40) and again update as above.
I'm using below query, but it will update the first 20 records after next 20 (21-40) records it will not work.
Update tableName set Column = 'TEXT1' where column = 'TEXT' ;
or if need be conditionally update...
UPDATE tablename set column = case when column = 'TEXT' then 'Text1'
else column = 'OtherText' then 'Text1Other'
else column = 'StillOtherText' then 'Text1Other2' end
WHERE column in ('TEXT','OtherText','StillOtherText');
One way is to use a while-loop that checks for the existence of 'TEXT'. If the check returns true, then the top 20 primary keys are selected as part of an update statement.
WHILE EXISTS (SELECT *
FROM Table1
WHERE yourcolumn = 'TEXT')
BEGIN
UPDATE Table1
SET yourcolumn = 'TEXT1'
WHERE primarykey IN (
SELECT TOP 20 primarykey
FROM Table1
WHERE yourcolumn = 'TEXT'
)
END

CASE STRUCTURE IN A DB2 SQL UPDATE

I need to update a value (FIELD_E) in one table based on the value in a field of a second table as long as certain conditions are met. Here is what I am working with thus far.
TABLE_1.FIELD_C is a primary key
TABLE_2.FIELD_D is a foreign key
There is a ONE TO MANY relationship between TABLE_1.FIELD_C AND TABLE_2.FIELD_D
UPDATE TABLE_1
SET TABLE_1.FIELD_E = (
CASE
WHEN
(
SELECT MAX(FIELD_A)
FROM TABLE_1,
TABLE_2
WHERE TABLE_1.FIELD_C = TABLE_2.FIELD_D
AND TABLE_1.FIELD_A IS NOT NULL
AND TABLE_2.FIELD_B IS NULL) = 'Y' THEN '1'
WHEN
(
SELECT MAX(FIELD_A)
FROM TABLE_1,
TABLE_2
WHERE TABLE_1.FIELD_C = TABLE_2.FIELD_D
AND TABLE_1.FIELD_A IS NOT NULL
AND TABLE_2.FIELD_B IS NULL) = 'N' THEN '10'
WHEN
(
SELECT MAX(FIELD_A)
FROM TABLE_1,
TABLE_2
WHERE TABLE_1.FIELD_C = TABLE_2.FIELD_D
AND TABLE_1.FIELD_A IS NOT NULL
AND TABLE_2.FIELD_B IS NULL) = 'U' THEN '9'
ELSE NULL
END
WHERE TABLE_1.FIELD_C = TABLE_2.FIELD_D
AND TABLE_1.FIELD_A IS NOT NULL
AND TABLE_2.FIELD_B IS NULL
I know I could probably do this more simply by just taking a snapshot and writing multiple statements using primary keys but if the values were to change after the snapshot and before the update, an incorrect update could be made.
Can I get some suggestions on how to do this using a similar case structures statement?
Your query is doing several things you likely do not intend, besides the blatant syntax and construction errors. Making some assumptions about reasonable behavior, the query can be a lot simpler than your current effort:
UPDATE Table_1 SET field_e = CASE field_a WHEN 'Y' THEN '1'
WHEN 'N' THEN '10'
WHEN 'U' THEN '9'
ELSE null END
WHERE field_a IS NOT NULL
AND EXISTS (SELECT '1'
FROM Table_2
WHERE Table_2.field_d = Table_1.field_c
AND Table_2.field_b IS NULL)
SQL Fiddle Example
Your original query had the following behavior or other problems:
Your subqueries were certainly returning more than one row (error)
Your outermost SELECT mentions Table_2 without providing a reference (error)
There was no correlation between the outer UPDATE and any of the subqueries, meaning everything would be updated to have 1, regardless of the actual contents of a particular row's field.
I'm also not sure if you want the ELSE NULL in your CASE - this has the effect of erasing whatever value is currently in field_e if field_a doesn't have a matching value. Or rather, not restricting the update to those rows containing the values interested in (because ELSE null is implied if excluded).

2 SQL Updates in 1 statement

Im trying to do something like the following:
UPDATE table SET fieldA='valueA' WHERE id='id1', SET fieldB='valueB' WHERE id='id2';
But cant seem to get it to work. Is there a way of doing this, or will I need to use two separate SQL commands?
If you really need to do it in one statement, you can use this:
UPDATE table
SET fieldA = case when id = 'id1' then 'valueA' else fieldA end,
fieldB = case when id = 'id2' then 'valueB' else fieldB end
WHERE id in ('id1', 'id2');
But for clarity (and thus maintainability), it would be much better to use two statements.
This is best done as 2 different UPDATE statements, because you have 2 different WHERE clauses:
UPDATE table SET fieldA='valueA' WHERE id='id1'
UPDATE table SET fieldB='valueB' WHERE id='id2'
MERGE INTO YourTable
USING ( VALUES ( 'id1', 'valueA', NULL ),
( 'id2', NULL, 'valueB' ) )
AS source ( id, fieldA , fieldB )
ON YourTable.id = source.id
WHEN MATCHED THEN
UPDATE
SET fieldA = COALESCE(source.fieldA, YourTable.fieldA),
fieldB = COALESCE(source.fieldB, YourTable.fieldB);
You'll need to use 2 separate SQL-statements because the set operator works on the whole resultset that's filtered by the where-clause.
UPDATE table SET fieldA='valueA' WHERE id='id1'; UPDATE table SET fieldB='valueB' WHERE id='id2';
UPDATE table SET fieldA='valueA',fieldB='valueB' WHERE id in ('id1','id2')