update 3 columns in 1 uppdate - sql

I'm writing a query to update a table. The table has many fields among which there are 3 fields: column1, column2, column3 each of which can be null.
The data is loaded every day. On day 1 a row can come in which
column1 is null,
column2 is not null
column3 is null.
The next day there may be a row where
column1 is not null,
column2 is null,
column3 is null.
The idea is to insert new rows, and those rows which are identical to previously uploaded ones, but which column1, column2, column3 change are not inserted, but updated.
I tried to write a query to update all three fields at once. But in case described above, I will change not null to null.
Does anyone know a way to update any of the fields in a single update query without writing null there?
for example:
update table2 upt
set column1 = n.column1,
column2 = n.column2,
column3 = n.column3
from (select new.column1, new.column2, new.column3, new.column4, new.column5
from table1 new
where new.column4 in (select old.column4 from table2 old
where old.column5 = new.column5
and (old.column1 is null or old.column2 is null or old.column3 is null)
and (new.column1 is not null or new.column2 is not null and new.column3 is not null) n
where upt.date_fielad = '2022-01-01'
and upt.column4 = n.column4
and upt.column5 = n.column5
and (upt.column1 <> n.column1
or upt.column2 <> n.column2
or upt.column3 <> n.column3)
How I can change this query to not update not null fields null?

Related

How to use CASE statement in SQL to change an empty field in one column based on another column

I'm just starting with SQL with no training but the job suddenly requires it. So thank you in advance for any help.
Let's say I have a query that returns 3 columns. Some of the cells in column 3 are empty and I would like to fill them in with values based on column1.
example:
CASE column1 = 'Individual' then Column3 should show 'Individual' not empty, but if column1 = 'group' them column3 needs to show "group" else no change.
SELECT column1, column2, column3,
CASE
WHEN column1 = 'Individual' THEN Column3 = 'Individual'
WHEN column1 = "Group' THEN comlumn3 = 'Group'
END
FROM tablename
If you only want to select data and not change the table values you can use case as you tried:
SELECT column1, column2,
CASE
WHEN column3 IS NULL THEN Column1
ELSE column3
END as column3
FROM tablename

How to do an update on a query having union in postgrsql?

I have 2 tables name test and test_snapshop. in test table i am saving the current data and in test_snapshot i am saving older data. Now i need to do an update against some id values.theer is a chance that some ids exist in test and some in snapshot table.
I tried like this
update test
set column1=value,
column2=value,
column3=value
where column4 in(1,2,3)
union
update test_snapshot
set column1=value,
column2=value,
column3=value
where column4 in(1,2,3)
Both tables have same no and name of column.
The above query is not as expected. what I am doing wrong in this query. can any one help me in this.
I am new to postgresql.
Although I voted to close as a typo, you can express this in Postgres using a single statement. I might go for:
with ids as (
select *
from (values (1), (2), (3)) v(id)
),
t as (
update test
set column1 = value,
column2 = value,
column3 = value
where column4 in (select i.id from ids i)
)
update test_snapshot
set column1 = value,
column2 = value,
column3 = value
where column4 in (select i.id from ids i);
With this structure, you only need to list the id values once.

PostgreSQL count multiple columns of the same table

I want to count some columns from a table in PostgreSQL.
For each column count I have some conditions and I want to have all in one query. My problem is the fact that I don't get the expected results in counting because I tried to apply all the conditions for the entire data set.
The table:
column1
column2
column3
UUID10
UUID20
UUID30
NULL
UUID21
NULL
NULL
UUID22
UUID31
UUID11
UUID20
UUID30
This is what I tried so far:
SELECT
COUNT(DISTINCT column1) AS column1_count,
COUNT(DISTINCT column2) AS column2_count,
COUNT(DISTINCT column3) AS column3_count
FROM TABLE
WHERE
column2 IN ('UUID20', 'UUID21', 'UUID22')
AND column1 = 'UUID10' -> this condition should be removed from this where clause
OR column3 IN ('UUID30', 'UUID31')
Result:
column1_count
column2_count
coumn3_count
2
3
2
The result in not correct because I should have column1_count = 1. I mean, this is what the query does, but is not what I intended. So I thought to have some constrains for column2 and column3 in a subquery, and having a another condition just for column1.
A second try:
SELECT *
FROM
(
SELECT
column1
column2,
column3
FROM TABLE
WHERE
column2 IN ('UUID20', 'UUID21', 'UUID22')
OR column3 IN ('UUID30', 'UUID31')
) x
WHERE
column1 = 'UUID10'
Result:
column1_count
column2_count
coumn3_count
1
1
1
Because the last condition on column1 is restricting my result, I end up having 1 for all the counts.
How can I apply different conditions for counting each column?
I would try not to use UNION if is possible. Maybe there can be made some subqueries in another way than what I tried so far. I just have to find a way for the constraint for the column1, to not be on the same WHEN clause as for the column2 and column3.
I think you want conditional aggregation:
SELECT COUNT(DISTINCT CASE WHEN column1 = 'UUID10' THEN column1 END) AS column1_count,
COUNT(DISTINCT column2) AS column2_count,
COUNT(DISTINCT column3) AS coumn3_count
FROM TABLE
WHERE column2 IN ('UUID20', 'UUID21', 'UUID22') OR
column3 IN ('UUID30', 'UUID31');
I assume that you are aware that COUNT(DISTINCT CASE WHEN column1 = 'UUID10' THEN column1 END) is not particularly useful code. It returns 1 or 0 depending on whether the value is present. I assume your code is actually more interesting.

SQL select earlier date (including NULL)

I am trying to select the earlier date/time from a two given columns. However, I am running into issues if one of the two columns have a null value.
my thought is
select case when dateTime1 < datetime2 then column1 else column2
end as EarlierDate
from table
However, using the above method will always return null values regardless how I change the greater or smaller sign.
You can have:
Select Case When Column1 is null then Column2 when Column2 is Null then Column1 When Column1 > Column2 Then Column2 When Column1 < Column2 Then Column1 End As EarlierDate From TableName

ORACLE UPDATE SAME TABLE

I am getting error while updating one set of data by applying condition (LESS THAN SYMBOL) with other set of data on same table. could someone please help me.
Below is my oracle query -
UPDATE TABLE
SET COLUMN1 = 1
WHERE COLUMN2 = 'Y'
AND COLUMN3 = 'N'
AND TRUNC(COLUMN4) <
(SELECT TRUNC(COLUMN4)
FROM TABLE
WHERE COLUMN3 = 'Y' AND COLUMN4 = 'Y')
ERROR AS BELOW -
SQL Error:
ORA-01427: single-row subquery returns more than one row
01427. 00000 - "single-row subquery returns more than one row"
*Cause:
*Action:
First some homework; please do not call your table TABLE (Oracle will complain). Additionally your subquery doesn't make sense:
(SELECT TRUNC(COLUMN4)
FROM TABLE
WHERE COLUMN3 = 'Y' AND COLUMN4 = 'Y')
If COLUMN4 = 'Y what does TRUNC(COLUMN4) mean?
But I guess what you mean is this (sample data added)
create table TAB as
select 1 COLUMN1, 'Y' COLUMN2, 'N' COLUMN3, sysdate-1 COLUMN4 from dual union all
select 2 COLUMN1, 'Y' COLUMN2, 'Y' COLUMN3, sysdate COLUMN4 from dual union all
select 2 COLUMN1, 'Y' COLUMN2, 'Y' COLUMN3, sysdate COLUMN4 from dual;
UPDATE TAB
SET COLUMN1 = 1
WHERE COLUMN2 = 'Y'
AND COLUMN3 = 'N'
AND TRUNC(COLUMN4) <
(SELECT TRUNC(COLUMN4)
FROM TAB
WHERE COLUMN2 = 'Y' AND COLUMN3 = 'Y');
Which leads to
ORA-01427: single-row subquery returns more than one row
The problem is, with < you can compare only two numbers, if you want to compare a number with a set of numbers (= result of a subquery with more rows), you must use the Group Comparison Conditions. Two choices are available:
< ALL - the predicate is valid for ALL values returned by the subquery
< ANY / < SOME the predicate is valid for SOME (at least one) value returned by the subquery .
So what you can do this for example
UPDATE TAB
SET COLUMN1 = 1
WHERE COLUMN2 = 'Y'
AND COLUMN3 = 'N'
AND TRUNC(COLUMN4) < ALL
(SELECT TRUNC(COLUMN4)
FROM TAB
WHERE COLUMN2 = 'Y' AND COLUMN3 = 'Y');
Update will be done in rows with TRUNC(COLUMN4) less than **ALL* values returned by the subquery.
I think the message is pretty clear. Perhaps you should use an aggregation function:
UPDATE TABLE
SET COLUMN1 = 1
WHERE COLUMN2 = 'Y' AND
COLUMN3 = 'N' AND
TRUNC(COLUMN4) < (SELECT MIN(TRUNC(COLUMN4))
FROM TABLE
WHERE COLUMN3 = 'Y' AND COLUMN4 = 'Y'
);
EDIT:
Given the columns you've specified, this could be simplified to:
UPDATE TABLE
SET COLUMN1 = 1
WHERE COLUMN2 = 'Y' AND
COLUMN3 = 'N' AND
TRUNC(COLUMN4) < 'Y';
You might need an additional condition, if the purpose of the subquery was to see if any rows exist.