I'm trying to use a Case formula to evaluate a date but it's erroring out every time. Not sure where I'm going wrong.
1/1/9999 is a date.
Code:
CASE
WHEN "Item "."Store OOS" = 1/1/9999
THEN 'repln'
ELSE 'Fashion'
END
CASE WHEN "Item"."Store OOS" = date '9999-01-01' then 'repln' ELSE 'Fashion' END
Related
I am getting two values one is printing Cash and other is printing CASH in sap crystal report. Now, I want that wherever Cash is showing at that time value should be false while if CASH is printing then the value should show true. So, for that I added the formula but didnt work,
here is my formula,
if(ProperCase({TmpSalesBillInstallmentReport.PaymentType}) = true)
then {TmpSalesBillInstallmentReport.PaymentType}= '0'
else if(UpperCase({TmpSalesBillInstallmentReport.PaymentType}) = true)
{TmpSalesBillInstallmentReport.PaymentType} = '1'
This formula is not working, even getting error i.e. A Boolean Is Required Here(indicating on the first line)
I surfing in net but didnt get related question also.
IF {TmpSalesBillInstallmentReport.PaymentType} = "CASH" Then True ELSE False;
Note: A Crystal formula cannot assign a value to a database field. The field value is Read Only!
UpperCase() function is not a test that returns true or false. It simply returns the text argument after converting it to all upper case.
You might have a setting causing comparisons to be case insensitive.
See: http://www.plumblineconsulting.com/crystal-reports-and-case-sensitivity-of-database-records/
I am trying to group certain source/medium dimensions in Google Data Studio and leave the original value for the rest; for example:
CASE
WHEN (source/medium = “lnkd.IN|linkedin.*”) THEN “Linkedin”
ELSE “”
END
Can the ELSE be blank to keep the same original value?
Put the column that you're updating in the ELSE clause, so it will assign the original value back to the column.
SET columnname = CASE WHEN (`source/medium` RLIKE 'lnkd\\.in|linkedin\\.') THEN 'Linkedin' ELSE columnname END
Your else clause should just be the column that you're testing on if you want it to remain unchanged. For example if your column name is "source/medium", it would be like this:
CASE WHEN (source/medium = “lnkd.in|linkedin.*”) THEN “Linkedin” ELSE source/medium END
I hope you can help I am attempting to use an If statement in Spotfire. What I am trying to achieve is this
I have 13 unique numbers and what I am trying to say is that if column [GL_ACCOUNT(2)] = any of these 13 numbers then return me "Not EFPIA" in my new calculated column 'GL Account Filter'
It works up to two numbers but once i increase the amount of numbers the formula will not work.
My Code is below. As always any help is greatly appreciated
if([GL_ACCOUNT(2)]="0063304000","0063401000", "0062001000", "Not EFPIA")
Without using TERR or JS or IronPY you'll have to explicitly OR these together. I think you are trying to do something like the IN clause in TSQL as explained here but I'm unaware of that functionality in Spotfire.
if([GL_ACCOUNT(2)]="0063304000" or
[GL_ACCOUNT(2)]="0063401000" or
[GL_ACCOUNT(2)]="0062001000", "Not EFPIA")
You can also do this with a CASE if that's more legible for you.
case
when [GL_ACCOUNT(2)] = "0063304000" then "Not EFPIA"
when [GL_ACCOUNT(2)] = "0063401000" then "Not EFPIA"
when [GL_ACCOUNT(2)] = "0062001000" then "Not EFPIA"
else NULL
end
Or with the OR....
case
when [GL_ACCOUNT(2)] = "0063304000" OR
[GL_ACCOUNT(2)] = "0063401000" OR
[GL_ACCOUNT(2)] = "0062001000" then "Not EFPIA"
else NULL
end
The expression can be used as
if([GL_ACCOUNT(2)] in "0063304000","0063401000", "0062001000", "Not EFPIA")
I have a table, that contains date field (let it be date s_date) and description field (varchar2(n) desc). What I need is to write a script (or a single query, if possible), that will parse the desc field and if it contains a valid oracle date, then it will cut this date and update the s_date, if it is null.
But there are one more condition - there are must be exactly one occurence of a date in the desc. If there are 0 or >1 - nothing should be updated.
By the time I came up with this pretty ugly solution using regular expressions:
----------------------------------------------
create or replace function to_date_single( p_date_str in varchar2 )
return date
is
l_date date;
pRegEx varchar(150);
pResStr varchar(150);
begin
pRegEx := '((0[1-9]|[12][0-9]|3[01])[.](0[1-9]|1[012])[.](19|20)\d\d)((.|\n|\t|\s)*((0[1-9]|[12][0-9]|3[01])[.](0[1-9]|1[012])[.](19|20)\d\d))?';
pResStr := regexp_substr(p_date_str, pRegEx);
if not (length(pResStr) = 10)
then return null;
end if;
l_date := to_date(pResStr, 'dd.mm.yyyy');
return l_date;
exception
when others then return null;
end to_date_single;
----------------------------------------------
update myTable t
set t.s_date = to_date_single(t.desc)
where t.s_date is null;
----------------------------------------------
But it's working extremely slow (more than a second for each record and i need to update about 30000 records). Is it possible to optimize the function somehow? Maybe it is the way to do the thing without regexp? Any other ideas?
Any advice is appreciated :)
EDIT:
OK, maybe it'll be useful for someone. The following regular expression performs check for valid date (DD.MM.YYYY) taking into account the number of days in a month, including the check for leap year:
(((0[1-9]|[12]\d|3[01])\.(0[13578]|1[02])\.((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\.(0[13456789]|1[012])\.((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\.02\.((19|[2-9]\d)\d{2}))|(29\.02\.((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))
I used it with the query, suggested by #David (see accepted answer), but I've tried select instead of update (so it's 1 regexp less per row, because we don't do regexp_substr) just for "benchmarking" purpose.
Numbers probably won't tell much here, cause it all depends on hardware, software and specific DB design, but it took about 2 minutes to select 36K records for me. Update will be slower, but I think It'll still be a reasonable time.
I would refactor it along the lines of a single update query.
Use two regexp_instr() calls in the where clause to find rows for which a first occurrence of the match occurs and a second occurrence does not, and regexp_substr() to pull the matching characters for the update.
update my_table
set my_date = to_date(regexp_subtr(desc,...),...)
where regexp_instr(desc,pattern,1,1) > 0 and
regexp_instr(desc,pattern,1,2) = 0
You might get even better performance with:
update my_table
set my_date = to_date(regexp_subtr(desc,...),...)
where case regexp_instr(desc,pattern,1,1)
when 0 then 'N'
else case regexp_instr(desc,pattern,1,2)
when 0 then 'Y'
else 'N'
end
end = 'Y'
... as it only evaluates the second regexp if the first is non-zero. The first query might also do that but the optimiser might choose to evaluate the second predicate first because it is an equality condition, under the assumption that it's more selective.
Or reordering the Case expression might be better -- it's a trade-off that's difficult to judge and probably very dependent on the data.
I think there's no way to improve this task. Actually, in order to achieve what you want it should get even slower.
Your regular expression matches text like 31.02.2013, 31.04.2013 outside the range of the month. If you put year in the game,
it gets even worse. 29.02.2012 is valid, but 29.02.2013 is not.
That's why you have to test if the result is a valid date.
Since there isn't a full regular expression for that, you would have to do it by PLSQL really.
In your to_date_single function you return null when a invalid date is found.
But that doesn't mean there won't be other valid dates forward on the text.
So you have to keep trying until you either find two valid dates or hit the end of the text:
create or replace function fn_to_date(p_date_str in varchar2) return date is
l_date date;
pRegEx varchar(150);
pResStr varchar(150);
vn_findings number;
vn_loop number;
begin
vn_findings := 0;
vn_loop := 1;
pRegEx := '((0[1-9]|[12][0-9]|3[01])[.](0[1-9]|1[012])[.](19|20)\d\d)';
loop
pResStr := regexp_substr(p_date_str, pRegEx, 1, vn_loop);
if pResStr is null then exit; end if;
begin
l_date := to_date(pResStr, 'dd.mm.yyyy');
vn_findings := vn_findings + 1;
-- your crazy requirement :)
if vn_findings = 2 then
return null;
end if;
exception when others then
null;
end;
-- you have to keep trying :)
vn_loop := vn_loop + 1;
end loop;
return l_date;
end;
Some tests:
select fn_to_date('xxxx29.02.2012xxxxx') c1 --ok
, fn_to_date('xxxx29.02.2012xxx29.02.2013xxx') c2 --ok, 2nd is invalid
, fn_to_date('xxxx29.02.2012xxx29.02.2016xxx') c2 --null, both are valid
from dual
As you are going to have to do try and error anyway one idea would be to use a simpler regular expression.
Something like \d\d[.]\d\d[.]\d\d\d\d would suffice. That would depend on your data, of course.
Using #David's idea you could filter the ammount of rows to apply your to_date_single function (because it's slow),
but regular expressions alone won't do what you want:
update my_table
set my_date = fn_to_date( )
where regexp_instr(desc,patern,1,1) > 0
I have a set of 7 checkboxes on my winForm that allow the user to select which days of the week they want assigned with the order being created. I am trying to create the IF Statement that implements these checkbox decisions correctly. I have tried many combination of If, IfElse, and Select statement but all to no avail.
If cbMon.Checked = True Then
.WriteString("Monday")
If cbTues.Checked = True Then
.WriteString("Tuesday")
If cbWed.Checked = True Then
.WriteString("Wednesday")
If cbThur.Checked = True Then
.WriteString("Thursday")
If cbFri.Checked = True Then
.WriteString("Friday")
If cbSat.Checked = True Then
.WriteString("Saturday")
If cbSun.Checked = True Then
.WriteString("Sunday")
End If
End If
End If
End If
End If
End If
End If
That what i have so far that works the best. The problem though is that if i check "Monday, Tuesday, and Thursday" on the winForm...Monday and Tuesday will show up, but Thursday gets skipped because it obviously breaks out of the if statement. Any guidance?
The problem is that you should not be nesting your if statements.
In your example, any portion of code will only hit if the day before it (all the way up to monday) is checked.
Simply flatten out the if statements, and do not nest them, like so :
If cbMon.Checked = True Then
.WriteString("Monday")
End If
If cbTue.Checked = True Then
.WriteString("Tuesday")
End If
...etc...
If you want the users to select only ONE option, perhaps a dropdown or radio button list is more suitable rather than checkboxes.
do not use nesting
just simple if loop is needed here
Initialise an array
if monday
add monday to array
if tuesday checked
add tuesday to array
.
.
.
if sunday checked
add sunday to array
get the string by append all values in array with ','
Yes your problem is that you are nesting your if statements, which is why Thursday gets skipped because Wednesday proved to be false.
What you need to do is run a for loop that will go through each check box and check whether its checked value is true.