Compare value against parameters in Drools - java

I am giving an object as an input in a Drools decision table.
This object has an "Amount" parameter.
What I would like to do is to compare this received value against a value present in a column in each row. How can I do that?
Basically, I want to compare the input.amount to the value on the same row in the right column.
How can I do that ?

You cannot refer to a value that's given in a column to the right, but it's possible the other way round. Therefore, the columns should be written along these lines (assuming Input is the class name of the object containing the amount):
CONDITION ACTION
Input
$amt:amount insertLogical(new RoutingResult("$param"));
Avail.bal.
100 $amt
200 $amt
300 $amt
If you join the cells, you don't have to repeat $amt in each row.

Related

What is a good way to remove duplicates?

I have a varchar column. It contains values separated by semicolon (;).
For example, it looks like
10;20;21;17;20;21;22;
It's not always 7 elements. It could contain anything from around 30 to 70. The reason they designed it this way is because the values are actually genome segments and it makes sense to enter or retrieve it collectively
I need to remove records with duplicate columns, so if I see another record with the same value as above, I need to remove it.
I also need to remove the record if it contains same values in another record. For example, I need to remove
10;;21;17;20;21;22;
because it's the same as the first but it doesn't have the second value, 20. If it's more complete than the first, I will remove the first one instead.
1;2;3;4;5;6;7; and 1;2;3;4;5;6;7;8; are dups and I'm taking the 2nd one because it's more complete. 1;2;3;4;5;6;;7 is also a duplicate. In this case, if they have 13 or more matched numbers and no mismatch, we will merge them so it becomes a single value 1;2;3;4;5;6;7;7;.
I can scan each record in java but I'm afraid that it will be complicated and time consuming, given that the table contains millions of records. I was wondering if it's doable in oracle itself.
My final goal is to calculate the frequency that those numbers occur. For instance, if number 10 appears 5 out of 100 times, it will be 5%. The calculation will be simple. However, I can't calculate this unless I make sure there's no duplicates in the table in the first place.
Note: This answer is a placeholder because the question looks in danger of closure but I think it will be worthy of an answer once all the rules are established.
It's trivial to remove the exact duplicates:
delete from your_table y
where y.rowid not in ( select min(x.rowid)
from your_table x
group by x.genome_string)
The hard part is establishing duplicating strings which have exact matches and nulls. Merging rows makes the logic even more convoluted.
The sql below is a solution ONLY IF:
1;2;3;4;5; is a more complete form of 1;2;;5
All your entries end with ;
The request was tested using sqlite so perhaps it may need some changes for Oracle.
It expects a table "TEST" with a column "VALUE"
SELECT
DISTINCT VALUE
from TEST As ORIGIN_TEST
WHERE NOT EXISTS (SELECT VALUE FROM TEST
WHERE
VALUE <> ORIGIN_TEST.VALUE AND
(VALUE LIKE replace(ORIGIN_TEST.VALUE, ';;', ';_%;') OR
VALUE LIKE ORIGIN_TEST.VALUE || '_%;')
)

Apache POI formula to check any of the cell from the range is not blank

I am working with Apache POI, using conditional formating. I want to be able to write a formula such as - if any of the columns from within the specified range is not a number then highlight all of them. I am trying to use with the formula - ISNUMBER($J1:P1000). But this does not work.
ConditionalFormattingRule rule = sheetCF.createConditionalFormattingRule("ISNUMBER($J1:P1000))");
If I try with just single cell with formula - ISNUMBER($J1) it works. But I want condition if any of the cells through J to P is a number then do some highlighting.
Details of code to highlight some cells based on some rule is given in this thread, so not repeating- Apache POI - Conditional formatting - need to set different cell range for rule and formatting
As I understand the question now (also took comments into account), the requirement is to highlight the whole range J1:P[n] (I will take J1:P1000 for example) if any of the cells within this range contains numeric content. This is posible using a formula as the ConditionalFormattingRule.
Background knowledge:
Conditional formatting (CF) works having rules applied to a range of cells and having formats to use if the rule is fulfilled. While CF process runs, each cell in the applied range is tested whether it fulfills the rule. If so, the format will be used, if not, then not.
So if the rule is a formula, then we must look at this formula from point of view of each single cell in the range. There it plays a important role
whether cell references in the formula are relative or are fixated using $.
In cell references the $ can fixing the column reference as well as the row reference. For example in A1 both, the column reference as well as the row reference, are relative. In $A1, the column reference to column A is fix and the row reference is relative. In A$1, the column reference is relative and the row reference to row 1 is fix. In $A$1 both, the column reference to column A as well as the row reference to row 1 are fix. So this last reference will always referencing cell A1.
The concrete examples:
In my answer Apache POI - Conditional formatting - need to set different cell range for rule and formatting, which is related to this answer, a formula rule: AND(ISNUMBER($C1), $C1>5) is applied to the range G1:L1000. So from point of view the single cell in G1:L1000, the rule checks the following:
Is the cell value in column $C (always in column C because this reference is fixated), in same row where the single cell exists (because the row references are relative), numeric and greater than 5?
In comment I have suggested a rule AND(ISNUMBER($C1), $C1>5, G1="") applied to the same range G1:L1000. This checks the same as the above and:
Is the single cell in columns G:L, where the single cell exists, (not always in column G because the column reference is relative), in same row where the single cell exists (because the row references are relative), empty (equals an empty string)?
Now your actual requirement:
"to highlight the whole range J1:P1000 if any of the cells within this range contans numeric content"
The function COUNT does only count numbers. So COUNT($J$1:$P$1000) will be greater than 0 if any cell in J1:P1000 contains a number.
So
ConditionalFormattingRule rule = sheetCF.createConditionalFormattingRule("(COUNT($J$1:$P$1000)>0)");
applied to CellRangeAddress.valueOf("J1:P1000") could work as you wants.
From point of view the single cell for each cell the COUNT must count the whole range. Thats why the references in $J$1:$P$1000 are all fixated and are not relative.

How to search row index using cell value

I am using google spreadsheet API v4 for java.
My Spreadsheet looks something like this -
User Message Time
--------------------------------
User1 My Message 10:30
User2 User2 msg 3:40
User3 User3 msg 1:30
User2 User2 msg
User4 User4 msg 4:00
I want to find row index with User 'User2' and Time bank (empty value).
After that, I would like to use this row index to add time value in that row.
Is it possible to search row by cell values without knowing range or index?
In above example, it should return me only second last row index as it matches to the criteria (User='User2' and Time='').
or even better, is there any find and replace API, which will find row criteria (User='User2' and Time='') and replace Time value from '' to '3:30'?
I went through google docs, but could not find one according to my need.
Thanks.
Edit:
I found a formula to find cell address which needs to be updated.
=ADDRESS(MATCH("User2",A1:A4000),3)
For example used in this question, this formula will return '$C$4' address, which is expected. I tested this by evaluating this formula in spreadsheet manually. Is there any way using Google spreadsheet API V4 to evaluate this formula using Java code?
I think you'd want to use a combination of lookup functions:
https://support.google.com/docs/topic/3105472?hl=en&ref_topic=3046366
In particular, MATCH lets you get a position offset of the value you want in a range, so you could get the offset of the cells in column1 containing values 'User2', and OFFSET could let you check the value in the cell 2 columns to the right of the found cell, which would give you the value in the Time column to compare with. Since then you'd also have the cell coordiates of the thing checked, you could then assign a new value. These lookup functions allow you to find the range or index that you need for the rest.
This just gives you a handy way to have certain values precomputed for your other functions so that your script can get direct access to values output by the sheets builtin functions. It saves having to have your sheets script sort through a range for a value, but the logic is the same.
1) Get range for Column1
2) Search range of Column1 for value 'User2'
3) If matched, check offset(0,2) to get the cell reference 2 spaces to the right and ask for its cell reference.
4) If that reference is empty, assign it a timestamp.
If you want the code for this, it'll take me a bit longer to put together.

How to have multiple values for a key in cypher query for neo4j?

I am working with a program that i have a record for every user. My users have a property with key, PhoneNumber , and its value is an array of strings, [454457,897356]. For example if i wanted to use cypher query:
Start n=node(1)
Return n
It returns 1 record for my node(one row) that the value of column PhoneNumber is an array.
But i want to have record numbers according to the number of values in my array, means that for my example, the query returns 2 records(2 rows) and all of its attributes be the same but in the PhoneNumber column one of them has the value 454457 and the other has the value 897356. Is any way to do that? do i change my cypher query or make some changes in my java code?
Thanks.
There is no way to do that yet, within Cypher. I've submitted a request for it, though:
https://github.com/neo4j/neo4j/issues/30

Type of collection to use for 3 row values, 2 of which must be multiplied

i am returning results from a sql query which contains multiple rows of three columns.
Column1(a rate) must be multiplied by column2(a numerical value). Column 3 consists of five different possible values. Each value will indicate a condition that column1 and column2 must adhere to( basically column3 will be another value (like an exchange rate)- but it has not yet been determined, so I would like to group this value with the result of the other two.
Obviously a collection of some sort ought to be used, but i am not sure which will allow me to efficiently deal with multiplying column1 by column2 and noting the value for column3 and multiplying this at a later date. So far, I have something like this:
(obviously ill probably need a for loop)
double value= "column1";
double rate= "column2";
double currency= "column3";
Finalamount setValue(value);
Finalamount setRate(rate);
Finalamount setCurrency(currency);
Collection <Finalamount> col = new ArrayList();
You ought to write a custom class that abstracts all this away from clients. It'll document and encapsulate what needs to be done and simply handles it so it's all set when clients get the query results back.
Looks like you're already on the right track. Just type your array list and give it a better name:
Collection <Finalamount> finalAmounts = new ArrayList<Finalamount>();

Categories