Update one column value with another column value using SQL Query - sql

I have a table which has three columns with integer values. In first two columns I have some values. Now I need to update the third column with the value which is minimum of other two columns.
I have tried using
update table set col3 = (SELECT CASE WHEN (col2 is null OR col1 < col2 )
THEN col1
ELSE col2
END AS col3
FROM table
WHERE col1 is not null or col2 is not null)`.
But I am getting an error like below:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

You can use LEAST in order to update:
UPDATE mytable
SET col3 = LEAST(COALESCE(col1, col2), COALESCE(col2, col1))
WHERE col1 IS NOT NULL OR col2 IS NOT NULL
You don't have to query your table table to get col2, col1 values. You can use them directly in the SET part of your UPDATE query.
Note: COALESCE is used to handle NULL values. If both col1, col2 are NULL then col3 is also set to NULL.
In SQL Server you can use:
UPDATE mytable
SET col3 = CASE
WHEN col2 IS NULL OR col1 < col2 THEN col1
ELSE col2
END
WHERE col1 IS NOT NULL OR col2 IS NOT NULL
In SQL Server 2012, or later, you can use IIF:
UPDATE mytable
SET col3 = IIF(col2 IS NULL OR col1 < col2, col1, col2)
WHERE col1 IS NOT NULL OR col2 IS NOT NULL
Demo here

You don't need to join to the table it self, you can use the data from the columns in the same query
update table
set col3 = CASE WHEN (col2 is null OR col1 < col2 )
THEN col1 ELSE col2 END
WHERE col1 is not null or col2 is not null
The problem with your query is that you are using a correlated query, that selects col1 and col2(which is basically fine but unnecessary) and you are not filtering the results(which col1,col2 to take?) so for each col3 you want to update, you have a 'bunch' of other values, when you can only have 1. If you want your query to work all you have to do is add a relation condition.

Related

What happens if I compare a column with itself and it is NULL?

What happens if I compare a column with itself and it is NULL ? Is this similar to floating point values where x == x only is false if the value is a NaN ?
It depends on the comparison you do with itself.
If you do
WHERE Col = Col
any rows where Col IS NULL will have the WHERE clause evaluate to UNKNOWN (rather than TRUE or FALSE) and the row will not be returned.
So WHERE Col = Col is equivalent to WHERE Col IS NOT NULL
If you do (not available in all RDBMS but standard SQL)
WHERE Col IS NOT DISTINCT FROM Col
Then this will evaluate to true
The comparsion with = is not NULL safe, which means the result is UNKNOWN
So you should check your database for NULL safe comparisons
On MySQL it is <=>
Postgres uses col1 IS DISTINCT FROM col2
SQL Server hasn't one till Version 2022, you can uses the last option in query. Since Version 2022 it also supports col1 IS DISTINCT FROM col2
SELECT col1 = col2,col1 <=> col2, col1 = col2 OR (col1 IS NULL AND col2 IS NULL) FROM tab1
col1 = col2
col1 <=> col2
col1 = col2 OR (col1 IS NULL AND col2 IS NULL)
null
1
1
fiddle

I am trying to return Col1 as a value for a list, IF Col2 = NULL

I am trying to return all Col1 values IF the respective Col2 value = NULL
I have thought of IF Col2 = NULL Return Col2 END IF, But I am unsure of how to format this, because when I run it I get errors saying invalid relational operator. Thank you for your time.
SELECT Col1
FROM mytable
WHERE IF NULL Col2 = 0;
IF Col2 = NULL
RETURN COL1
ELSE
END IF;
================================================================
EDIT
I apologize for the lack of information/Show of research. First post, So I have been searching google for different IF then statements to deal with NULL values. Everything I have found this far has only showed how to Ignore/convert to 0 so that you can easily work with them. Nothing on how to use them to return values from another col1
use COALESCE. it resturns the first non null value
SELECT
COALESCE(col1,col2) AS FINAL_COLUMN
FROM [TABLE NAME]
SELECT Col1
FROM mytable
WHERE Col2 IS NULL
No IF is required. WHERE is the SQL IF for row selection. This returns only the rows where Col2 is null.
If you want to return all the rows, but want to return Col1 when Col2 is null and NULL otherwise, use
SELECT
CASE WHEN Col2 IS NULL THEN Col1 ELSE NULL END as myResultColumn
FROM mytable

Sql Logical operators.. AND & OR combination

I have a sql code with filter conditions as below
Select * from TABLE A
Where Col1<>0
and(col2 is not null or col3 is not null)
Please explain why i do not see any records in the output when a record has NULL on both col2 and col3.
How is this is evaluated??
Null check for Col1 should be the first in condition. if Col1 is null then checking null with a value e.g. Col1 = 0 or Col1 <> 0 will always return false. Below an alternate way to deal with nulls in Col1.
Select * from TABLE A
Where isnull(Col1, 0) <> 0
and col2 is not null

SQL: Select the minimum value from multiple columns with null values

I have a table like this one
ID Col1 Col2 Col3
-- ---- ---- ----
1 7 NULL 12
2 2 46 NULL
3 NULL NULL NULL
4 245 1 792
I wanted a query that yields the following result
ID Col1 Col2 Col3 MIN
-- ---- ---- ---- ---
1 7 NULL 12 7
2 2 46 NULL 2
3 NULL NULL NULL NULL
4 245 1 792 1
I mean, I wanted a column containing the minimum values out of Col1, Col2, and Col 3 for each row ignoring NULL values. In a previous question (What's the best way to select the minimum value from multiple columns?) there is an answer for non NULL values. I need a query as efficient as possible for a huge table.
Select Id,
Case When Col1 < Col2 And Col1 < Col3 Then Col1
When Col2 < Col1 And Col2 < Col3 Then Col2
Else Col3
End As MIN
From YourTableNameHere
Assuming you can define some "max" value (I'll use 9999 here) that your real values will never exceed:
Select Id,
Case When Col1 < COALESCE(Col2, 9999)
And Col1 < COALESCE(Col3, 9999) Then Col1
When Col2 < COALESCE(Col1, 9999)
And Col2 < COALESCE(Col3, 9999) Then Col2
Else Col3
End As MIN
From YourTableNameHere;
You didn't specify which version of Teradata you're using. If you're using version 14+ then you can use least.
Unfortunately least will return null if any of its arguments are null. From the docs:
LEAST supports 1-10 numeric values.
If numeric_value is the data type of the first argument, the return
data type is numeric. The remaining arguments in the input list must
be the same or compatible types. If either input parameter is NULL,
NULL is returned.
But you can get around that by using coalesce as Joe did in his answer.
select id,
least(coalesce(col1,9999),coalesce(col2,9999),coalesce(col3,9999))
from mytable
This might work:
Select id, Col1, Col2, Col3, least(Col1, Col2, Col3) as MIN From YourTableNameHere
in this way you don't need to check for nulls, just use min and a subquery
select tbl.id,tbl.col1,tbl.col2,tbl.col3,
(select min(t.col)
from (
select col1 as col from tbl_name t where t.id=tbl.id
union all
select col2 as col from tbl_name t where t.id=tbl.id
union all
select col3 as col from tbl_name t where t.id=tbl.id
)t)
from tbl_name tbl
Output:
1 7 NULL 12 7
2 2 46 NULL 2
3 NULL NULL NULL NULL
4 245 1 792 1
Just modify your query with coalesce():
Select Id,
(Case When Col1 <= coalesce(Col2, col3, col1) And
Col1 <= coalesce(Col3, col2, col1)
Then Col1
When Col2 <= coalesce(Col1, col3, col2) And
Col2 <= coalesce(Col3, col1, col2)
Then Col2
Else Col3
End) As MIN
From YourTableNameHere;
This doesn't require inventing a "magic" number or over-complicating the logic.
I found this solution to be more efficient than using multiple case statement clauses, which can get extremely lengthy when evaluating data from several columns across one row.
Also, I can't take credit for this solution as I found it on some website a year or so ago. Today I needed a refresh on this logic, and I couldn't find it anywhere. I found my old code and decided to share it in this forum now.
Creating your test table:
create table #testTable(ID int, Col1 int, Col2 int, Col3 int)
Insert into #testTable values(1,7,null,12)
Insert into #testTable values(2,2,46,null)
Insert into #testTable values(3,null,null,null)
Insert into #testTable values(4,245,1,792)
Finding min value in row data:
Select ID, Col1, Col2, Col3 ,(SELECT Min(v) FROM ( VALUES (Col1), (Col2), (Col3) ) AS value(v)) [MIN] from #testTable order by ID

Get record with a field egal to a specific value else with null

I want in SQL : if a field is equal to a specific value, I want this record if not I want the record with this field equal to null.
I can try to that:
SELECT TOP 1 COL1, COL2, COL3
FROM TABLE1 WHERE (COL2 = MY_SPECIFIC_VALUE OR COL2 IS NULL) AND COL3 = '42'
AND COL1 = 3
But, what is the result returned? The smallest id? Or it is not specified?
Assuming that this is the real question:
If a field is equal to a specific value, I want this record if not I want the record with this field equal to null.
You can do this as:
SELECT TOP 1 COL1, COL2, COL3
FROM TABLE1
WHERE (COL2 = MY_SPECIFIC_VALUE or COL2 IS NULL) AND
COL3 = '42' AND COL1 = 3
ORDER BY (CASE WHEN COL2 = MY_SPECIFIC_VALUE THEN 1 ELSE 2 END);