SQL getting the minimum out of calculation of 3 values - sql

I have multiple rows that each have 3 columns and what I want to do is calculate these 3 columns at each row and see which row has the lowest sum
for example:
row 1 - col1(1)+col2(3)+col3(0) = 4
row 2 - col1(50) + col2(3) + col3(4) = 57
row 3 - col1(2) + col2(0) + col3(0) = 2
the selected row (row 3) will show me the calculated value = 2
currently I have been calculating only by 1 column but now I need 3
this is what I was doing:
select min(Bonus) from dbo.Bonuses AS c1
my table (Bonuses)
ID Bonus Double Bonus Master Bonus
1 1 3 0
2 50 3 4
3 2 0 0
expected results:
the row 3 is the minimum in value will print
2

you can do it with:
select min(col1 + col2 + col3) from table;
col1 + col2 + col3 - calculate sum of every line (row) of the table;
min(col1 + col2 + col3) - determine minimal value.
In your case:
select min("Bonus" + "Double Bonus" + "Master Bonus") from "Bonuses";

You shoul get the minimum among columns first, for each row, then get the minimum from result column:
select min(least(col1, col2, col3)) from yourTable;

Just in case, you should know that NULL values could have an unexpected result. The safer calculation is:
select min(coalesce(col1, 0) + coalesce(col2, 0) + coalesce(col3, 0))
The issue with NULL values is that the + returns NULL if any values are NULL. That means that all values from that row would be ignored.
The sample data in the question doesn't have NULL values. But it also doesn't specify that the values are never NULL, so I think this is important to point out.

Related

How to sum non-null values from multiple columns (workaround for CASE WHEN limitation) Postgresql

So I essentially want to work around the fact that CASE WHEN stops executing when it finds its first TRUE return.
I'd like to sum every instance of a non-null value between multiple columns, and group these based on my ID. Example table:
id
input1
input2
input3
1
a
null
k
2
null
null
b
3
null
null
null
4
q
null
r
5
x
p
j
6
null
y
q
I would like the output of my function to be:
id
total_inputs
1
2
2
1
3
0
4
2
5
3
6
2
Any work arounds? Is a custom function in order to create a count of unique or non-null entries across multiple columns, grouped by row?
I know I can create a CTE and assign 1's to each non-null column but that seems tedious (my data set has 39 inputs) - and I'd like to have a reusable function I could use again in the future.
You could use a simple aggregation as the following:
Select id,
Count(input1) + Count(input2) + Count(input3) As total_inputs
From table_name
Group By id
Order By id
Noting that Count(inputX) = 0, where inputX is null.
See a demo.
We can simply use:
select ID,
case when input1 is not null then 1 else 0 end
+ case when input2 is not null then 1 else 0 end
+ ...
+ case when input39 is not null then 1 else 0 end as total_inputs
from ...
No need to group by if you want every row (or count, we are not aggregating rows - that is what COUNT()..GROUP BY is for), or CTE.
Also, for some PostgreSQL versions, there is a num_nulls function to count null parameters:
select
, 32-num_nulls(input1, input2, input3, ..., input32)

Returning the maximum of non-null columns ​from a table

I have a table with 4 columns, one of which is a non-null column, all others can be given a null value.
I just want a SELECT that returns results that have as many non-null columns as possible.
For example:
If I have 5 records in my Table, 1 of those records will have 3 columns with data, 2 of them will have 2 columns with data and 2 of them will have only 1 column with data. In my select, I want as a result only the first option: to bring me 3 columns with data. But it can be just 2 columns with data, it will be dynamic according to the table to be updated.
I'm using Oracle SQL.
One option is a conditional sort based on the count of non-null values in each row, and then a row-limiting clause (available since Oracle 12c). Assuming that the 3 nullable columns are col1, col2 and col3, that would be:
select *
from mytable
order by
case when col1 is null then 0 else 1 end
+ case when col2 is null then 0 else 1 end
+ case when col3 is null then 0 else 1 end desc
fetch first row with ties
If you are running an older version of Oracle, you can get the same result with window function rank():
select *
from (
select
t.*,
rank() over(order by
case when col1 is null then 0 else 1 end
+ case when col2 is null then 0 else 1 end
+ case when col3 is null then 0 else 1 end desc
) rn
from mytable t
) t
where rn = 1

Query to find occurrence of at least one value in a set of columns

In the below table, how do I filter out records with at least one 1 and at least one 2 in any of the columns. I also only want records for columns with the string 2nd row in the Name column.
Col1 Col2 Col3 Col4 Name
1 1 1 1 1st row
1 2 1 2 2nd row
2 1 1 1 3rd row
1 2 2nd row
I want the output to be -
Col1 Col2 Col3 Col4 Name
1 2 1 2 2nd row
1 2 2nd row
You can use IN as a shortcut for "col1" = 1 OR ....
SELECT *
FROM "elbat"
WHERE 1 IN ("col1",
...,
"col4")
AND 2 IN ("col1",
...,
"col4")
AND "name" = '2nd row';
You can use Postgres' arrays for that:
select *
from the_table
where array[1,2] <# array[coalesce(col1, -1), coalesce(col2, -1), coalesce(col3, -1), coalesce(col4, -1)]
and name = '2nd row';
The <# operator checks, if all elements of the left hand array are included in the right hand array. The coalesce() is necessary because you can't put null values into an array.
Online example: https://rextester.com/CLXWK64603
If you want you can create an index on the array expression to speed things up.

SQL adding numbers while handling nulls

I have this statement here:
SELECT sum(table1.foo + table1.bar) AS Sum
FROM table1
GROUP BY Fname;
When I try to add the numbers from foo and bar if one value from foo or bar is null it throws the numbers and gives me a different count sum
foo | bar
6 4
5 null
9 1
2 1
3 null
I want it to add all the numbers giving me a total of 31
but in this case it gives me a total of 23
Would love some help! Thanks!
Use coalesce():
SELECT sum(coalesce(table1.foo, 0) + coalesce(table1.bar, 0)) AS Sum
FROM table1
GROUP BY Fname;
If you want the total, total on one row, remove the group by:
SELECT sum(coalesce(table1.foo, 0) + coalesce(table1.bar, 0)) AS Sum
FROM table1;
Any Number + NULL = NULL. You want to indicate to the engine that when it sees a NULL, it should treat that NULL value as 0.
SELECT sum(ISNULL(table1.foo, 0) + ISNULL(table1.bar,0)) AS Sum
FROM table1
GROUP BY Fname;
I believe you'll need to have SQL replace nulls with a zero using "ISNULL".
Try:
SELECT sum(ISNULL(fix_bat_sum.foo, 0) + ISNULL(fix_bat_sum.bar, 0) ) AS Sum

Filter based on all columns

I have a table with several columns and each column can have a value of 0 OR 1 ..I just want to eliminate the rows where all the columns have 0 .. I just want to consider the rows if at least one column have a value of 1
SELECT *
FROM A_TABLE_YOU_DID_NOT_NAME
WHERE col1 + col2 + ... + colN >= 1
Will not return all 0 and at least one of them will be 1.
IN SQL Server, you can make use of OR:
SELECT *
FROM table
WHERE [column1] = 1 OR [column2] = 1...