SQL: sum 3 columns when one column has a null value without replacing null with 0? - sql

Given table:
ID ANOTHERID ONE TWO THREE
X1 B1 15 15 -
X1 B2 10 - -
X2 B1 - 20 -
This query:
SELECT SUM (ONE + TWO + THREE) FROM (TABLE)
GROUP BY ID, ANOTHERID
I also tried
select sum(coalesce( ONE + TWO + THREE, ONE + TWO, ONE + THREE, ONE +
THREE))
at least one column has a null value. How can I still add them even if there is a null? As null and 0 have different meanings here (null means not started, 0 means not worked), I dont want to replace null with 0. Thanks

One method is:
SELECT SUM(COALESCE(ONE, 0) + COALESCE(TWO, 0) + COALESCE(THREE, 0))
FROM (TABLE)
GROUP BY ID, ANOTHERID;
Or, if you have at least one non-NULL value in each column:
SELECT SUM(ONE) + SUM(TWO) + SUM(THREE)

The time reporting table(s) should not allow null values, and the employee table should have a hire date field which can be used as criteria in your reporting queries. This will enable you to accurately report what management expects.

This solution worked for me
select
case when coalesce(sum(ONE), sum(TWO), sum(THREE)) is null then null else
sum(nvl(ONE,0) + nvl(TWO,0) + nvl(THREE,0)) end as
TOTALSUM
GROUP BY ID, ANOTHERID;

You might need to add another column in your table that describes the status of the employee (new, old) then make a condition like this:
if emp_status = 'new' then
--some code
working_hours := null;
else
--some code
working_hours : 0;
end if;

Related

Select the column not like and combine column in one table [duplicate]

This question already has answers here:
How to SUM two fields within an SQL query
(9 answers)
Closed 10 months ago.
My question is how can I select the currency not equal to USD and CNY and rename as others. Also, combining it into a new column AMT_Others.
ID Name Date AMT_HKD AMT_JPY AMT_USD AMT_TWD AMT_CNY
1 Amy 01/04/2022 0 5000 0 0 0
2 Bill 01/03/2022 200 0 0 0 0
3 Cathy 02/02/2022 0 0 80 2000 200
Result:
ID Name Date AMT_Others
1 Amy 01/04/2022 5000
2 Bill 01/03/2022 200
3 Cathy 02/02/2022 2000
my code: (It cannot generate what I want, what should be added? Thanks)
select ID, Name, Date, (AMT_HKD, AMT_JPY and AMT_TWD) as AMT_Others
basically add them up as long as we have only one non zero value for all currencies except USD and CNY
Select ID, Name, Date,
AMT_HKD + AMT_JPY + AMT_TWD as AMT_Others
from yourtable
You can get your desired result by using + instead of comma or AND:
SELECT id, name, ydate, amt_hkd + amt_jpy + amt_twd AS amt_others FROM yourtable;
But this is quite unpleasant in case there are null values in some of your columns. In this case, the sum would be null, too, even if some of the columns are not null. You can use COALESCE to prevent this and to force building a sum. Null values will be replaced by 0 (or another value if you change it):
SELECT id, name, ydate,
COALESCE(amt_hkd,0) + COALESCE(amt_jpy,0) + COALESCE(amt_twd,0) AS amt_others
FROM yourtable;
You can check this and see the difference between the two query results here: db<fiddle
You should also prevent table names or column names that are SQL key words, like the "date" column in your example. That'
s why I renamed it in my answer. Of course, if you can't change this, you have to live with it, but if you can, you should choose another name.
the other answers will work, unless there can be null values, if there is a row where one of these columns is ´null` then the result will also be null
select 1 + 2 -- output is 3
select 1 + 2 + null -- output is null
solution to this problem
isnull(AMT_HKD, 0) -- easy but slow
COALESCE(amt_hkd, 0) -- easy but still not the fastest solution
case when amt_hkd is null then 0 else amt_hkd end -- fastest
SELECT ID, Name, Date,
AMT_HKD + AMT_JPY + AMT_TWD as AMT_Others
FROM tb_name;
This will work

How to set flag based on values in previous columns in same table ? (Oracle)

I'm creating a new table and carrying over several columns from a previous table. One of the new fields that I need to create is a flag that will have values 0 or 1 and value needs to be determined based on 6 previous fields in the table.
The 6 previous columns have preexisting values of 0 or 1 stored for each one. This new field needs to check whether any of the 6 columns have 1 and if so set the flag to 0. If there is 0 in all 6 fields then set itself to 1.
Hopefully this makes sense. How can I get this done in oracle? I assume a case statement and some sort of forloop?
You can use greatest() function: GREATEST
create table t_new
as
select
case when greatest(c1,c2,c3,c4,c5,c6)=1 -- at least one of them contains 1
then 0
else 1
end c_new
from t_old;
Or even shorter:
create table t_new
as
select
1-greatest(c1,c2,c3,c4,c5,c6) as c_new
from t_old;
In case of greatest = 1, (1-1)=0, otherwise (1-0)=1
You can use a virtual column with a case expression; something like:
flag number generated always as (
case when val_1 + val_2 + val_3 + val_4 + val_5 + val_6 = 0 then 1 else 0 end
) virtual
db<>fiddle
or the same thing with greatest() as #Sayan suggested.
Using a virtual column means the flag will be right for newly-inserted rows, and if any of the other values are updated; you won't have to recalculate or update the flag column manually.
I've assumed the other six columns can't be null and are constrained to only be 0 or 1, as the question suggests. If they can be null you can add nvl() or coalesce() to each term in the calculation.

MS SQL Server: Operate current select values in other selected columns

I want to take a value from a selected column to operate the next column. For example:
SELECT CASE
WHEN ID < 4 THEN ID
ELSE 10
END
AS MY_ID,
MY_ID + 5 AS EXTRA_ID
FROM FOO
That would output for IDs 1,2,3,4,5:
MY_ID EXTRA_ID
1 6
2 7
3 8
10 15
10 15
If I do MY_ID + 5 it will complain about MY_ID not existing (it's an alias, so it makes sense) and ID + 5 will read 1+5, 2+5, 3+5, 4+5, 5+5 instead of 1+5, 2+5, 3+5, 4+10, 5+10 when it goes through the ELSE. Is it even possible to do this? I'm doing it in SSRS - Report builder, and need to operate a result that might be set to a defualt value depending on the CASE clause.
You can repeat the same CASE expression with +5 in the end for the extra_id column
SELECT CASE
WHEN ID < 4 THEN ID
ELSE 10
END
AS MY_ID,
CASE
WHEN ID < 4 THEN ID
ELSE 10
END + 5 AS EXTRA_ID
FROM FOO
An alternative is to create the extra_id column value inside SSRS using an expression
= Fields!my_id.value + 5
you cannot reuse the calculation in the same level. Using my_id in the where clause will fail as well. Either you have to calucate it multiple times, place another select around your statement or use a with statement (CTE).
Simply wrap it with another select:
SELECT t.*,
t.my_id + 5 as extra_id
FROM(Your Query) t
Derived columns are not available in the same layer they're being created. By wrapping them with another select, you make them available (that because the inner query is being processed before the outer) .
You just need a subquery to create MY_ID before doing anything with it. By creating MY_ID in the inner query the outer query can use to define new fields.
SELECT
a.MY_ID,
a.MY_ID + 5 AS EXTRA_ID
from
(SELECT
CASE
WHEN ID < 4 THEN ID
ELSE 10
END
AS MY_ID
FROM FOO) as a

SQL : select one column if two columns are equal, else select both

I have the following SQL select problem:
I have two columns positive threshold and negative threshold (among several other columns like name, ids.... ).
If their (absolute) value is the same (multiply by -1) then I want to select only the positive threshold as column [threshold].
If the values are different, I want to select two columns [positiveThreshold] and [negativeThreshold].
Thank you in advance.
select null as [threshold], positivethreshold, negativethreshold
from table
where negativethreshold is null
or (positivethreshold + negativethreshold) <> 0
union
select positivethreshold, null, null
from table
where (positivethreshold + negativethreshold) = 0

SQL query to add values of two columns containing null values?

Given table:
ID ONE TWO
X1 15 15
X2 10 -
X3 - 20
This query:
SELECT (ONE + TWO) FROM (TABLE)
Just returns the sum of X1's values but not the others since at least one column has a null value. How can I still add them even if there is a null? i.e. consider the null as a 0 maybe?
SELECT (COALESCE(ONE, 0) + COALESCE(TWO, 0)) FROM (TABLE)
COALESCE will return the first non-null value found in the parameters from left to right. So, when the first field is null, it will take the 0.
That way, X2 will result in 10 + 0 = 10
there is already a good answer, but I think it is worth mention to the antonpug (in case he doesn't know) that the reason why this is happening is that NULL is not a value that can be compared or summed.
NULL isn't 0 or '' (empty string), so every operation involving NULL will result NULL (10 + NULL = NULL), even (NULL=NULL) will evaluate to FALSE