I am dividing Field_A by Field_B. But the problem is that sometimes Field_A is NULL (doesn't have any value). How can i check for that?
If it is Null, i guess the result should be 0 or Null.
Use an IIF (inline If statement) in the expression:
=IIF(<Condition>,<TruePart>,<FalsePart>)
=IIF(Field_A Is Nothing OR Field_B = 0, 0, Field_A/Field_B)
This way, you are making sure that Field_A is not null and Field_B is not zero, to also avoid divide by zero errors.
The Easiest Method is to simply add a very small value to potential null value/zero value
So :
=IIF(Field_A Is Nothing OR Field_B = 0, 0, Field_A/( Field_B + .000001))
This will still give you 0 when the value is either null or zero, but will prevent the #error from showing up when the denominator is otherwise null or zero
Also : Be careful to make sure that your types are the same; meaning, if the data type of your Field_A is decimal or double, make sure that you cast the small amount .000001 to CDec(.000001)
I have found that making sure that all types in your expression are the same is key to avoiding the #Error message
Yes, I think what "Jammie F" has commented above is correct.If Field B is 0 then you will get Divide by zero error.
What you can use is:-
iif(Field_B=0,0,Field_A/Field_B)
Related
SELECT * FROM Entity e WHERE e.Status <> ANY(ARRAY[1,2,3]);
Here Status is a nullable integer column. Using the above query i am unable to fetch the records whose status value is NULL.
SELECT * FROM Entity e WHERE (e.Status is NULL OR e.Status = 4);
This query does the trick. Could someone explain me why the first query was not working as expected.
NULL kinda means "unknown", so the expressions
NULL = NULL
and
NULL != NULL
are neither true nor false, they're NULL. Because it is not known whether an "unknown" value is equal or unequal to another "unknown" value.
Since <> ANY uses an equality test, if the value searched in the array is NULL, then the result will be NULL.
So your second query is correct.
It is spelled out in the docs Array ANY:
If the array expression yields a null array, the result of ANY will be null. If the left-hand expression yields null, the result of ANY is ordinarily null (though a non-strict comparison operator could possibly yield a different result). Also, if the right-hand array contains any null elements and no true comparison result is obtained, the result of ANY will be null, not false (again, assuming a strict comparison operator). This is in accordance with SQL's normal rules for Boolean combinations of null values.
FYI:
e.Status is NULL OR e.Status = 4
can be shortened to:
e_status IS NOT DISTINCT FROM 4
per Comparison operators.
I have a requirement to load null if the total hours is less than previous total hours else the difference
iif(lesser(TOTAL_HOURS, PREVIOUS_TOTAL_HOURS),null(),TOTAL_HOURS-PREVIOUS_TOTAL_HOURS)
It gives me expression could not be evaluated.
Not all rows have values for these fields, some of them are null. They are numeric fields in database.
I just want to replace negative results with null
If you look at the document iif it says
iif(<condition> : boolean, <true_expression> : any, [<false_expression> : any]) => any
Based on a condition applies one value or the other. If other is
unspecified it is considered NULL. Both the values must be
compatible(numeric, string...).
Now as per your expression:
iif(lesser(TOTAL_HOURS, PREVIOUS_TOTAL_HOURS),null(),TOTAL_HOURS-PREVIOUS_TOTAL_HOURS)
since first value you have mentioned is of type null it expects TOTAL_HOURS-PREVIOUS_TOTAL_HOURS must also return a same type null
What you can try is:
iif(lesser(TOTAL_HOURS, PREVIOUS_TOTAL_HOURS),toInteger(null()),TOTAL_HOURS-PREVIOUS_TOTAL_HOURS)
OR
case(TOTAL_HOURS < PREVIOUS_TOTAL_HOURS, toInteger(null()), minus(TOTAL_HOURS,PREVIOUS_TOTAL_HOURS) )
I have field that has up to 9 comma separated values each of which have a string value and a numeric value separated by colon. After parsing them all some of the values between 0 and 1 are being set to an integer rather than a numeric as cast. The problem is obviously related to data type but I am unsure what is causing it or how to fix it. The problem only exists in the case statement, the split_part function seems to be working perfect.
Things I have tried:
nvl(split_part(one,':',2),0) = COALESCE types text and integer cannot be matched
nvl(split_part(one,':',2)::numeric,0) => Invalid input syntax for type numeric
numerous other cast/convert variations
(CASE WHEN split_part(one,':',2) = '' THEN 0::numeric ELSE split_part(one,':',2)::numeric END)::numeric => runs but get int value of 0
When using the split_part function outside of case statement it does work correctly. However, I need the result to be zero for null values.
split_part(one,':',2) => 0.02068278096187390979 (expected result)
When running the code above I get zero but expect 0.02068278096187390979
Field "one" has the following value 'xyz: 0.02068278096187390979' before the split_part function.
EXAMPLE:
create table test(one varchar);
insert into test values('XYZ: 0.50000000000000000000')
select
one ,split_part(one,':',2) as correct_value_for_those_that_are_not_null ,
case
when split_part(one,':',2) = '' then null
else split_part(one,':',2)::numeric
end::numeric as this_one_is_the_problem
from test
However, I need the result to be zero for null values.
Your example does not deal with NULL values at all, though. Only addressing the empty string ('').
To replace either with 0 reliably, efficiently and without casting issues:
SELECT part1, CASE WHEN part2 <> '' THEN part2::numeric ELSE numeric '0' END AS part2
FROM (
SELECT split_part(one, ':', 1) AS part1
, split_part(one, ':', 2) AS part2
FROM test
) sub;
See:
Best way to check for "empty or null value"
Also note that all SQL CASE branches must agree on a common data type. There have been minor adjustments in the logic that determines the resulting type in the past, so the version of Postgres may play a role in corner cases. Don't recall the details now.
nvl()is not a Postgres function. You probably meant COALESCE. The manual:
This SQL-standard function provides capabilities similar to NVL and IFNULL, which are used in some other database systems.
original query looks like this :
UPDATE reponse_question_finale t1, reponse_question_finale t2 SET
t1.nb_question_repondu = (9-(ISNULL(t1.valeur_question_4)+ISNULL(t1.valeur_question_6)+ISNULL(t1.valeur_question_7)+ISNULL(t1.valeur_question_9))) WHERE t1.APPLICATION = t2.APPLICATION;
I know you cannot update 2 tables in a single query so i tried this :
UPDATE reponse_question_finale t1
SET nb_question_repondu = (9-(COALESCE(t1.valeur_question_4,'')::int+COALESCE(t1.valeur_question_6,'')::int+COALESCE(t1.valeur_question_7)::int+COALESCE(t1.valeur_question_9,'')::int))
WHERE t1.APPLICATION = t1.APPLICATION;
But this query gaves me an error : invalid input syntax for integer: ""
I saw that the Postgres equivalent to MySQL is COALESCE() so i think i'm on the good way here.
I also know you cannot add varchar to varchar so i tried to cast it to integer to do that. I'm not sure if i casted it correctly with parenthesis at the good place and regarding to error maybe i cannot cast to int with coalesce.
Last thing, i can certainly do a co-related sub-select to update my two tables but i'm a little lost at this point.
The output must be an integer matching the number of questions answered to a backup survey.
Any thoughts?
Thanks.
coalesce() returns the first non-null value from the list supplied. So, if the column value is null the expression COALESCE(t1.valeur_question_4,'') returns an empty string and that's why you get the error.
But it seems you want something completely different: you want check if the column is null (or empty) and then subtract a value if it is to count the number of non-null columns.
To return 1 if a value is not null or 0 if it isn't you can use:
(nullif(valeur_question_4, '') is null)::int
nullif returns null if the first value equals the second. The IS NULL condition returns a boolean (something that MySQL doesn't have) and that can be cast to an integer (where false will be cast to 0 and true to 1)
So the whole expression should be:
nb_question_repondu = 9 - (
(nullif(t1.valeur_question_4,'') is null)::int
+ (nullif(t1.valeur_question_6,'') is null)::int
+ (nullif(t1.valeur_question_7,'') is null)::int
+ (nullif(t1.valeur_question_9,'') is null)::int
)
Another option is to unpivot the columns and do a select on them in a sub-select:
update reponse_question_finale
set nb_question_repondu = (select count(*)
from (
values
(valeur_question_4),
(valeur_question_6),
(valeur_question_7),
(valeur_question_9)
) as t(q)
where nullif(trim(q),'') is not null);
Adding more columns to be considered is quite easy then, as you just need to add a single line to the values() clause
When in column must be stored only 2 values: 0 or 1,
What is the best column type choice for this column: "char" or ENUM('0', '1')?
As mentioned in the comments, this should be neither char nor enum, but a boolean.
FALSE translates to 0.
TRUE translates to1.
If you want to disallow NULL values define the column NOT NULL.