Basic Syntax vs SQL Command -- Formula Crystal Reports - crystal-reports

I am trying to convert this statement into a SQL command-- for testing and learning purposes.
The code in a formula in basic syntax is
if IsNumeric (Mid(Trim(X), 1)) Then
formula = UCASE(TRIM(MID(X, (INSTR (X, " ", 1) +1)))))
ELSE
formula = X.
What am I supposed to use instead of formula in the sql command and should this be done in sql command for efficiency? Even if I am not supposed to, I would like to know how to write this in sql command.
So far I have
CASE ISNUMERIC (Mid(Trim(X), 1)) Then
[BLANK] = UCASE(TRIM(MID(X, (CHARINDEX (X, " ", 1) +1)))))
ELSE
[BLANK] = X
EPV
Sample of Data. So when I import/link data from the back end. My X Field looks like a variety of:
1. 'zzabc123 - The Red Car'
2. 'abc123 - The Black Car'
3. 'The green car'
I want to create a SQL code where:
CHECK X (zzabc123 - the red car) to see if there is a zzabc123 in the front
if it is numeric, then cut out the front part - by using charindex to find where the space starts and grab only 'the red car'.
If it is not numeric, just clean up the DATA part
END CASE
After that case evaluate the DATA and use another CASE to find key words to use a generalized term for reporting.
RESULTS
RED CAR
BLACK CAR
GREEN CAR
SELECT *,
CASE ISNUMERIC(Mid(Trim(X), 1)) Then
UCASE(TRIM(MID(X, (CHARINDEX (X, " ", 1) +1)))))
ELSE X
END
CASE WHEN X LIKE '%RED%'
THEN 'RED CAR'
ELSE X LIKE '%BLACK%;
THEN 'BLACK CAR'
ELSE X LIKE '%GREEN%'
THEN 'GREEN CAR'
ELSE XY
END
FROM XTABLE`

Without knowing the specifics of your data and what you are trying to accomplish, it's next to impossible to accurately give you a SQL sample.
That said, here is a conversion of most of your functions to their SQL-Server equivalents; if you can look up items like the SUBSTRING() and CHARINDEX() functions, and adapt the sample to do whatever it is your requirements dictate, this should get you started.
SELECT
CASE
WHEN ISNUMERIC(SUBSTRING(LTRIM(RTRIM(X)), 1,1)) = 0
THEN UPPER(LTRIM(RTRIM(SUBSTRING(X, CHARINDEX(X, ' ')+1, LEN(X) - CHARINDEX(X, ' ')))))
ELSE 'X'
END
FROM MyTable

Try this:
CASE
WHEN ISNUMERIC (Mid(Trim(X), 1)) THEN
UCASE(TRIM(MID(X, (CHARINDEX (X, " ", 1) +1)))))
ELSE
X
END

Related

How can I convert this select statement to functional form?

I am having a couple of issues to put this in a functional format.
select from tableName where i=fby[(last;i);([]column_one;column_two)]
This is what I got:
?[tableName;fby;enlist(=;`i;(enlist;last;`i);(+:;(!;enlist`column_one`column_two;(enlist;`column_one;`column_two))));0b;()]
but I get a type error.
Any suggestions?
Consider using the following function, adjust from the buildQuery function given in the whitepaper on Parse Trees. This is a pretty useful tool for quickly developing in q, this version is an improvement on that given in the linked whitepaper, having been extended to handle updates by reference (i.e., update x:3 from `tab)
\c 30 200
tidy:{ssr/[;("\"~~";"~~\"");("";"")] $[","=first x;1_x;x]};
strBrk:{y,(";" sv x),z};
//replace k representation with equivalent q keyword
kreplace:{[x] $[`=qval:.q?x;x;"~~",string[qval],"~~"]};
funcK:{$[0=t:type x;.z.s each x;t<100h;x;kreplace x]};
//replace eg ,`FD`ABC`DEF with "enlist`FD`ABC`DEF"
ereplace:{"~~enlist",(.Q.s1 first x),"~~"};
ereptest:{((0=type x) & (1=count x) & (11=type first x)) | ((11=type x)&(1=count x))};
funcEn:{$[ereptest x;ereplace x;0=type x;.z.s each x;x]};
basic:{tidy .Q.s1 funcK funcEn x};
addbraks:{"(",x,")"};
//where clause needs to be a list of where clauses, so if only one whereclause need to enlist.
stringify:{$[(0=type x) & 1=count x;"enlist ";""],basic x};
//if a dictionary apply to both, keys and values
ab:{$[(0=count x) | -1=type x;.Q.s1 x;99=type x;(addbraks stringify key x),"!",stringify value x;stringify x]};
inner:{[x]
idxs:2 3 4 5 6 inter ainds:til count x;
x:#[x;idxs;'[ab;eval]];
if[6 in idxs;x[6]:ssr/[;("hopen";"hclose");("iasc";"idesc")] x[6]];
//for select statements within select statements
//This line has been adjusted
x[1]:$[-11=type x 1;x 1;$[11h=type x 1;[idxs,:1;"`",string first x 1];[idxs,:1;.z.s x 1]]];
x:#[x;ainds except idxs;string];
x[0],strBrk[1_x;"[";"]"]
};
buildSelect:{[x]
inner parse x
};
We can use this to create the functional query that will work
q)n:1000
q)tab:([]sym:n?`3;col1:n?100.0;col2:n?10.0)
q)buildSelect "select from tab where i=fby[(last;i);([]col1;col2)]"
"?[tab;enlist (=;`i;(fby;(enlist;last;`i);(flip;(lsq;enlist`col1`col2;(enlist;`col1;`col2)))));0b;()]"
So we have the following as the functional form
?[tab;enlist (=;`i;(fby;(enlist;last;`i);(flip;(lsq;enlist`col1`col2;(enlist;`col1;`col2)))));0b;()]
// Applying this
q)?[tab;enlist (=;`i;(fby;(enlist;last;`i);(flip;(lsq;enlist`col1`col2;(enlist;`col1;`col2)))));0b;()]
sym col1 col2
----------------------
bah 18.70281 3.927524
jjb 35.95293 5.170911
ihm 48.09078 5.159796
...
Glad you were able to fix your problem with converting your query to functional form.
Generally it is the case that when you use parse with a fby in your statement, q will convert this function into its k definition. Usually you should just be able to replace this k code with the q function itself (i.e. change (k){stuff} to fby) and this should run properly when turning the query into functional form.
Additionally, if you check out https://code.kx.com/v2/wp/parse-trees/ it goes into more detail about parse trees and functional form. Additionally, it contains a script called buildQuery which will return the functional form of the query of interest as a string which can be quite handy and save time when a functional form is complex.
I actually got it myself ->
?[tableName;((=;`i;(fby;(enlist;last;`i);(+:;(!;enlist`column_one`column_two;(enlist;`column_one;`column_two)))));(in;`venue;enlist`venueone`venuetwo));0b;()]
The issues was a () missing from the statement. Works fine now.
**if someone wants to add a more detailed explanation on how manual parse trees are built and how the generic (k){} function can be replaced with the actual function in q feel free to add your answer and I'll accept and upvote it

PySpark RDD Filter with "not in" for multiple values

I have an RDD looks like below:
myRDD:
[[u'16/12/2006', u'17:24:00'],
[u'16/12/2006', u'?'],
[u'16/12/2006', u'']]
I want to exclude the records with '?' or '' in it.
Following code works for one by one filtering, but is there a way to combine and filter items with '?' and '' in one go to get back following:
[u'16/12/2006', u'17:24:00']
The below works only for one item at a time, how to extend to multiple items
myRDD.filter(lambda x: '?' not in x)
want help on how to write:
myRDD.filter(lambda x: '?' not in x && '' not in x)
Try this,
myRDD.filter(lambda x: ('?' not in x) & ('' not in x))

How to compute a function on a set of natural numbers using recursion

I am working on a property of a given set of natural numbers and it seems difficult to compute. I build a function 'fun' which takes two inputs, one is the cardinal value and another is the set. If the set is empty then fun should return 0 because fun depends on the product of the set and fun on all subsets of the complement set.
For clarification here is an example:
S is a set given S={1,2,3,4}. The function fun(2,S) is defined as
fun(2,S)=prod({1,2})*[fun(1,{3}) + fun(1,{4}) + fun(2,{3,4})] +
prod({1,3})*[fun(1,{2}) + fun(1,{4}) + fun(2,{2,4})] +
prod({1,4})*[fun(1,{3}) + fun(1,{2}) + fun(2,{2,3})] +
prod({2,3})*[fun(1,{4}) + fun(1,{1}) + fun(2,{1,4})] +
prod({2,4})*[fun(1,{1}) + fun(1,{3}) + fun(2,{3,1})] +
prod({3,4})*[fun(1,{1}) + fun(1,{2}) + fun(2,{1,2})]
prod is defined as the product of all elements in a set, for example
prod({1,2})=2;
prod({3,2})=6
I am trying to compute the function fun using recursive method in MATLAB but it's not working. The base case is the cardinal value should be more than zero that means there should be at least one element in the set other wise prod will be zero and fun will return zero.
Update Pseudo code:
fun(i,S)
if |S|=1 && i!=0
return prod(S)
else if i==0
return 0
else
prod(subset s', s' is a subset of S and |s'|=i)*(sum over fun((for i=1 to m),{S-s'}), m=|S-s'|) //I don't know how to write code for this part and need help.
end if
end fun
prod(s)
n=|s|
temp=1
for i=1 to n
temp *=s(i) //s(1) is the 1st element of s
end for
return temp
end prod
Thanks.
With the pseudo code you added to your question it's nearly impossible to implement the function. Everything is put into one line which is incomplete (at least the outer sum is missing).
1) Formalize your algorithm in a way it can be used to implement. The following pseudo code is probably not correct because I don't exactly know what you want, but it should give an idea how to do it.
fun(i,S)
if i==0
return 0
else if |S|=1
return S
else
r=0
for s1 in subsets of S with size i
f=0
for s2 in subsets of setdiff(S,s') with size <=i
f=f+fun(s2,|s2|)
end
r=r+prod(s1)*f
end for
end if
end fun
2) use arrays [1,2,3,4] instead of cells {1,2,3,4}
3) prod is a built-in function, no need to reimplement it.

Extracting numbers from a string in crystal reports 9

I am trying to perform a quick fix for a client. We have a report field that shows tolerance values in strings like +/-20 , -19 +18. This is in micrometer and the client wants it in millimeter. So i need to divide only the numeric part of this string by 1000 and display the result.
I am relatively new to crystal reports, with my limited knowledge and from searching this site for suggestions, i created a function with the following code lines,
Function (stringvar x)
local stringvar array input := split(x,"+/-");
val(input[ubound(input)])/1000
The above function works perfectly for tolerance values of +/-. However i am not able to figure out a way to do it for '-19 +18'. I would like to have the result as -0.019 +0.018
I can easily do it in the database source and send it to the report. However the client needs a quick fix of just the report. Any help would be greatly appreciated.
try this
if(Left (x, 3 )="+/-")
then ToNumber(split(x ,"+/-")[2])/100
else if(Left ({x , 1 )="+")
then ToNumber(split(x ,"+")[2])/100
else if(Left (x , 1 )="-")
then ToNumber(split(x ,"-")[2])/100
I figured out an answer which would work for this specific case.
I used the following conditions in a formula field. Based on the condition I called a User defined function 'Tolerance','Tolerance2', 'Tolerance3'.
Formula field:
IF (Left ({PDPRINTDATA.PD_T45}, 3 )="+/-") THEN
'+/-' + ToText(Tolerance({PDPRINTDATA.PD_T45}),3)
ELSE IF (Left ({PDPRINTDATA.PD_T45} , 1 )="-") THEN
'-' + ToText(Tolerance2({PDPRINTDATA.PD_T45}),3) + ' +' + ToText(Tolerance3({PDPRINTDATA.PD_T45}),3)
Tolerance:
Function (stringvar x)
local stringvar array input := split(x,"+/-");
val(input[ubound(input)])/1000;
Tolerance2:
Function (stringvar x) local stringvar mystr := x;
If NumericText (mystr[2 to 3]) Then
ToNumber(mystr[2 to 3])/1000
Else 0
Tolerance3:
Function (stringvar x)
local stringvar mystr := x;
If NumericText (mystr[7 to 8]) Then
ToNumber(mystr[7 to 8])/1000
Else
0
This solution works for me considering the fact that the string will always be of this format '+/-XX' or '-XX +YY'.

How to put " <" to this CASE WHEN expression?

In PostgreSQL this is a valid query:
SELECT case 2+2 when 1 then 2 else 3 end
If I put a complex subquery instead of '2+2' it still works well. But how can I change this query if i want to know if the result is smaller than a specific number?
For example this one doesn't work:
SELECT case 2+2 when > 1 then 2 else 3 end
There are two forms of the CASE statement in SQL, described in the PostgreSQL manual here.
One, which you are using, compares a particular expression to a series of values, like a switch statement in C or PHP:
CASE something WHEN 1 THEN 'hello' ELSE 'goodbye' END
The other is a more general set of branching conditions, like an if-elseif-else sequence, or PHP's switch(true). The above can also be written like this:
CASE WHEN something = 1 THEN 'hello' ELSE 'goodbye' END
So to use any comparison other than =, you need the "if-like" version. In your example:
SELECT CASE WHEN 2+2 > 1 THEN 2 ELSE 3 END
select case when 2+2 > 1 then this else that end