Crystal Reports If true then return number else return NULL - crystal-reports

In Crystal Reports, is it possible to have a function that returns a numeric value if the if statement evaluates to true and returns NULL otherwise?
I currently have
IF ({INDICATOR} = 'Y') Then
(
{numeric value}
)
Else
(
0
);
But since 0 is a possible value of {numeric value} it doesn't make sense. Rather, I would rather have that field come up blank if the indicator isn't 'Y', but when I replace the 0 with NULL it gives me a type mismatch error.
Is there a way for me to only show the value when the indicator is 'Y'?

If you truly want a null value and not empty try the following
create a formula called NULL then save it and close without entering any data in the formula area. Then in your formula above try
If {INDICATOR} = 'Y' then {numeric value}
else tonumber({#NULL})

you can't return two different datatypes in a single if statement..If if is number then else should also be number.. instead try to split the statements and try.. something like below.
IF ({INDICATOR} = 'Y') Then
(
ToText({numeric value})
)
Else if ({INDICATOR} <> 'Y') Then
(
""
);

If {INDICATOR} = 'Y' then {numeric value}
else {Command.NULLCOL}
The setup in Database Expert is to use Add Command with sql:
select null as nullcol
from dual
Then left join to it.
A returned null value can be very powerful, so your need for a null value should not be questioned. Null values automatically display differently to stand out. Compared to 0 or "", null values work correctly with DistinctCount function. Null values also work correctly with section summaries and crosstabs, which can save you a lot of work which is the whole point of using crystal.

Related

Cast to int instead of decimal?

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.

Update with ISNULL and operation

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

Data Conversion error in SQL, unsure what field it could be referring to

Msg 8114, Level 16, State 5, Line 1 Error converting data type varchar to numeric.
Below is the code that I am using and the schema for the fields mentioned in the code. Some context behind this, I have a set list of indcodes. I only give one below but there are 350 in total. It is quite likely when i query by indcode, area, and ownership that the data does not exist. Hence, why I have the isnull language. Finally, I need rows that contains a value of suppress = 1 to show up as N/A.
For every indcode that I query, I need a result. The result could be actual data or some text (NULL, N/A, etc).
Last is the intended result. I only gave code for one indcode but have included six to give the example some depth.
select
CASE
WHEN suppress = 0 then isnull (mnth1emp, 0)
ELSE 'N/A'
END as mnth1emp,
CASE
WHEN suppress = 0 THEN isnull (mnth2emp, 0)
ELSE 'N/A'
END as mnth2emp,
CASE
WHEN suppress = 0 THEN isnull (mnth3emp, 0)
ELSE 'N/A'
END as mnth3emp
from dbo.industryimport20172f
where area='000003' and indcode='21' and ownership='00'
suppress char (1)
mnth1emp numeric(9,0)
mnth2emp numeric(9,0)
mnth3emp numeric(9,0)
area char(6)
indcode char (6)
ownership char(2)
123 456 789
1 2 3
Null null null
2 3 4
3 4 5
Null Null Null
So the first things that jump out here are:
a) While you're asking for numbers to be returned in the case statement, you're then asking for a string when you get to ELSE. Try casting all the fields as varchars and then entering them as strings:
CASE
WHEN cast(suppress as varchar) = '0' then isnull (cast(mnth1emp as varchar), '0')
ELSE 'N/A'
END as mnth1e
You may not need to cast suppress.
b) Does supress ever have anything other than a number in it? If so, you would need to put the zero as a string:
CASE WHEN supress = '0' --etc.

how to check null value of a string and if it is null then suppress any table in crystal report

I am trying to suppress a sub-report.I want to check a string value either it is null or not.
If the string value is null then it will suppress.
I followed the following steps-
then I wrote a formula like
if InStr ({EmployeeHist.SpouseName},'' ) = 0 then
'N/A'
But its showing a error THE FORMULA RESULT MUST BE A BOOLEAN..
Can anyone please help??
change the formula to
ISNULL({EmployeeHist.SpouseName})
this will return true if the SpouseName is null and the subreport will be suppressed
Change the formula like this
if InStr ({EmployeeHist.SpouseName},'' ) = '' then true else false

How to write custom function in crystal report to be used for record selection

I am confused in writing custom function in crystal report to fetch record using record selection.
When we create formula in record selection it will add where clause in the generated SQL-Query on the basis of parameters used. Now i want to write the custom formula, which will extract the record pro-grammatically :
Even i have written a function :
Function (stringVar st)(
stringVar selection;
if (st <> 'ALL') then (
selection = st;
)
else(
//In this case the user select only single value, it will fetch the result to that //particular column value in the table.. otherwise it leaves that particular row..
selection = "multiple selection";
)
)
Now the code to use the custom function in record selection using select expert would be :
if(myfunction({?parameter1}) <> "ALL") then
(
// what code should i write to select that particular record...
if(myfunction({?parameter2})) <> "ALL" ) then
(
//do selection from the previously selection of rows which have this parameter
if(myfunction({?parameter3}) <> "ALL") then
(
//do selection from the previously selection of rows which have this
//parameter
)
else (//do something else)
)
else (//do something else)
)
else (//do something else)
Thanks, in advance.
You don't need a custom function for this. Assuming that you have two string parameters, ry:
// assumes you have a parameter value of 'All Countries' w/ a value of '0'
( '0' IN {?CountryCodes} OR {table.CountryCode} IN {?CountryCodes} )
// assumes you have a parameter value of 'All Regions' w/ a value of '0'
AND ( '0' IN {?RegionCodes} OR {table.RegionCode} IN {?RegionCodes} )