Filter condition BIRT - equal - filter

I'm trying to create a filter condition, to show all results when this field is equal to 30 OR to 31.
I'm using this, but this is only showing for '30'.

The expression in brackets on the right side of the Equals to is evaluated first. ('30' || '31') returns always '30' (try it in a JavaScript evaluator) so equals to can always compare to only one value.
You need to place your expression in the left side (click the fx) like this:
row["agg::agg_field_id"] == '30' || row["agg::agg_field_id"] == '31'
Than you replace the Equals to from the drop down with is True and you are done.

Related

IIF and DATEADD Issue in SSRS Report

I’m trying to add three new columns into a report I’ve already created. I’d like to sum up the item quantities by their age. So, the first column would be the total quantity for each item for the last 0-7 days, second would be for the last 7-14 days and the last would be +14 days.
This is what I have currently:
=IIF(Fields!Date.Value >= DATEADD(DateInterval.Day, -7, FormatDateTime(Today)), SUM(Fields!Qty.Value))
I’ve tried modifying this in several ways but all (including the expression above) are underlined in red indicating that there is an error.
I’ve tried:
= IIF(Fields!Date.Value >= DATEADD(DateInterval.Day, -7, Now()), SUM(Fields!Qty.Value))
= IIF(Format(Fields!Date.Value, “dd/mm/yyyy”) >= DATEADD(DateInterval.Day, -7, Format(Today(), “dd/mm/yyyy”)), SUM(Fields!Qty.Value))
I’m at a loss as I don’t really write expressions too often. Am I going about this the wrong way?
The issue with your IIF is that there isn't an ELSE condition after the SUM. The IIF will return the value if the condition is true and the if not.
IIF(< condition >, < true >, < false >)
Also you want the sum to be outside the IIF in this instance, otherwise it will check the first date and if it matches add all the quantities from all dates.
=SUM(IIF(Fields!Date.Value >= TODAY.AddDays(-7), Fields!Qty.Value, 0))
If the Qty field is a decimal, the 0 may need conversion with CDEC(0).

Putting a zero in a Report Builder expression

I have an expression in my report in Report Builder that can have 0 for the sum but when it is displayed it shows "There are Job Reqs at this time." instead of "There are 0 (or 'no') Job Reqs at this time.". How can I get the 0 (or 'no') in this statement?
It's unclear what you are asking, but it sounds like if it is zero, it is actually returning blank. So doing something like this:
=IIF(
ISNOTHING(Fields!MightBeZeroValue.Value) OR
Fields!MightBeZeroValue.Value) = "",
"0",
Fields!MightBeZeroValue.Value)
This means that if the 'MightBeZeroValue' field is null or empty, display zero, otherwise display that field. Hope this helps.
If you can do this within the SQL, then even better:
SELECT
ISNULL(MightBeZeroValue.Value, 0) AS MightBeZeroValue
FROM
SomeTable

How to use CASE statement and a parameter in the WHERE clause?

I have an SSRS report where there is a parameter that asks the user to include records where revenue is greater than zero, or records with revenue values that are just zero.
Since the query is not a stored procedure and it is not an option to put it into a procedure, I need to use some case logic for the embedded query. I need to do this in the where clause in the end.
I am trying to do something like this:
SELECT * FROM TABLE
WHERE MY_DATE BETWEEN D_START AND D_END
AND
CASE
WHEN :REVENUE = 1 THEN REV != 0
WHEN :REVENUE = 2 THEN REV = 0
END
However, when I run this query I get the following error:
ORA-00905: missing keyword
Is what I am doing not possible? Or is there an error that someone can see and help me with?
Please help. Thanks!
UPDATE: Just to clarify, the user is passing a value of 1 or 2. And the query should filter the data according to what value is passed to it. If 1 is passed in the parameter, then filter out all revenue not equal to zero. Else if two is passed, then filter so that only records where revenue is zero is returned.
You can write it better with a bit of boolean logic:
SELECT * FROM TABLE
WHERE MY_DATE BETWEEN D_START AND D_END
AND (
(:REVENUE = 1 AND REV != 0)
OR
(:REVENUE = 2 AND REV = 0 )
)
CASE is meant to extract different values based on conditions, so you can use it to check conditions, but you need to use it as a value to check against a condition
It's not necessary to use a CASE expression to get this particular result.
But it is possible to make use of one.
The problem in the original query is that Oracle is more strict than other databases (like MySQL) in that Oracle doesn't implicitly convert a boolean expression to a value, or convert a value into boolean.
I suspect that Oracle is choking in a couple of places. The error message is only showing us one of those.
The CASE expression returns a value, and Oracle is balking that he won't evaluate the value as a boolean.
To get that value evaluated as a boolean, we could do a comparison of the value to some other value.
If we fix that, I think Oracle is still going to choke on the expression following THEN. Oracle is expecting to return a value, and it's finding a comparison, which evaluates to a boolean.
Okay, so we know the CASE expression needs to return a value, and we need to use that in a boolean expression. If we move that conditional test into the WHEN part, and specify a value to be returned in the THEN, we can compare the return from the CASE expression to another value.
(As an aside... I strongly recommend that you qualify the column references in the SQL statement. That makes the intent more clear. Looking at the statement, it looks like MY_DATE, D_START and D_END are all column references. That's perfectly valid, it just seems a bit odd to me.)
As an example, we could do something like this with the CASE expression:
SELECT t.*
FROM TABLE t
WHERE t.MY_DATE BETWEEN t.D_START AND t.D_END
AND CASE
WHEN ( :REVENUE = 1 AND t.REV != 0 ) THEN 1
WHEN ( :REVENUE = 2 AND t.REV = 0 ) THEN 1
ELSE NULL
END = 1
The parens inside the CASE aren't necessary; I just included them to highlight the part that Oracle is evaluating in a boolean context.
So, does that work? If the value passed in for :REVENUE is 2, the condition in the first WHEN won't evaluate to TRUE (the result of first comparison is guaranteed to be FALSE). The condition in the second WHEN may evaluate to TRUE (first comparison will yield TRUE, the result from second comparison will depend on the value in the REV column.)
That CASE expression is either going to return a value of 1 or NULL. (We could just as easily use a 0 or a -1, or 999 in place of NULL if we wanted.)
Once the CASE expression is evaluated, the value returned will be compared to a literal value, as if we wrote e.g. val = 1. That comparison is evaluated as boolean. If it evaluates to TRUE, the row will be returned...
To get Oracle to behave similarly to other databases (like MySQL), we would need to make the conversion from boolean to value and value to boolean explicit. We would still need the return from the CASE compared to 1, like we did above. In place of REV != 0 we could use another CASE expression. I'm not recommending this, just shown here for illustration, converting a boolean to a value.
WHERE CASE
WHEN ( :REVENUE = 1 )
THEN CASE WHEN ( t.REV != 0 ) THEN 1 ELSE NULL END
WHEN ( :REVENUE = 2 )
THEN CASE WHEN ( t.REV = 0 ) THEN 1 ELSE NULL END
ELSE
NULL
END = 1
Note that the return from the outermost CASE expression is being compared to a value, so we get a boolean (where Oracle expects a boolean.)
All of the ELSE NULL in the statements above can be omitted for an equivalent result, since that's the default when ELSE is omitted.)
Again, it's not necessary to use a CASE expression. You can get equivalent results without it. For example:
SELECT t.*
FROM TABLE t
WHERE t.MY_DATE BETWEEN t.D_START AND t.D_END
AND ( ( :REVENUE = 1 AND t.REV != 0 )
OR ( :REVENUE = 2 AND t.REV = 0 )
)
In these queries that all return an equivalent result, the CASE expression doesn't buy us anything. But in some circumstances, it can have some advantages over a regular OR, because the CASE expression stops evaluation when a condition in a WHEN clause evaluates to TRUE.
The problem is that Oracle SQL does not have the boolean data type, so you cannot have columns of type boolean, pass boolean parameters to a query, have boolean expressions etc. So they have the somewhat unnatural concept of "condition" which is something that goes into logical conditions (like in the WHERE clause). Unfortunately, when they introduced the case EXPRESSION, which can be used wherever any other expression can be used (but this excludes boolean), they DID NOT introduce a "case CONDITION" - which could be used where other conditions can be used. This omission is odd, since the code for a case condition would probably use 95% of the code for the case expression. All the more weird since PL/SQL does have the boolean type, and the case expression there works seamlessly for Booleans.

Oracle NOT BETWEEN for string comparison does not give same result as <= and >=

Using Oracle 11gR2 Expression Edition.
My data looks like following
ordertype
---------
ZOCO
ZOSA
ZOST
We are trying to find out records where the column is not between a certain range of values.
If I run a query with <= and >= operators:
SELECT * FROM table where ordertype <= 'ZAAA' OR ordertype >= 'ZZZZ';
then I get 0 results. This is the right answer.
However, if I use NOT BETWEEN:
SELECT * FROM table where ordertype NOT BETWEEN 'ZAAA' AND 'ZZZZ';
, then it gives multiple hits.
My understanding is that both syntax should give the same result but they are not. What am I missing? Reason I want to use NOT BETWEEN because a lot of our existing code already has this syntax and I do not want to change it without understanding the reasons.
Thank you.
Thanks for all those who posted. I ran the queries again and after fixing the "OR" in the first query, the results are the same. I still have the question of why Oracle character sorting is not recognizing it as expected, but my question which is about difference between NOT BETWEEN and <> was a false alarm. I apologize for confusion.
SELECT * FROM table where ordertype <= 'ZAAA' AND ordertype >= 'ZZZZ';
No string can be <= 'ZAAA' and >= 'ZZZZ'.
You need to use a disjunction instead:
SELECT * FROM table where ordertype < 'ZAAA' OR ordertype > 'ZZZZ';
BTW, given that BETWEEN is inclusive, NOT BETWEEN is exclusive
This is a common pitfall. you have to remember the De Morgan's Laws:
not (A and B) is the same as (not A) or (not B)
Feel free to experiment with this simple live example to convince yourself that those results are quite coherent: http://sqlfiddle.com/#!4/d41d8/38326
That being said, the only way (I can see) for the string like ZOCO for not being between ZAAA and ZZZZ would be:
having some hidden character just behind the Z (i.e.: 'Z'||CHR(0)||'OCO')
or using a locale such as Z-something is actually considered as a different letter, with a collation order outside of the given range. I don't know if such locale exists, but for example, in Welch, LL is considered as a single letter that should be sorted after the plain L. See http://en.wikipedia.org/wiki/Alphabetical_order#Language-specific_conventions
or having homogplyphs such as 0, 𐒠 or О instead of O in your data.
If it's not between the values, it has to be either < OR >, not AND.
In the first query, you ask for the records that are at the same time less than 'ZAAA' and also greater than 'ZZZZ'. Of course, there is no such value that fullfills both requirements, hence zero records are returned.
In the second query, you ask for records, that are either less than 'ZAAA' or greater than 'ZZZZ' (ie not between those boundaries [not between...]). There is a possibility that such records exist, and as your select statement proves, there are indeed such records, that are returned by the statement.
Your understanding that both statements are same is incorrect. NOT BETWEEN is not evaluated the way you're thinking. It simply returns the results which fall outside evaluation of BETWEEN for the parameters.
IF you check Oracle documentation for BETWEEN, it says -
The value of
expr1 NOT BETWEEN expr2 AND expr3
is the value of the expression
NOT (expr1 BETWEEN expr2 AND expr3)

How to use checkbox values in code?

In my Oracle APEX application page I have checkbox item with multiple values. The source of checkbox is like this:
STATIC:One,Two,Apple
In page process I need to use the value from checkbox in PL/SQL code. As far as I understand I get colon separated values. Question is how to use those values and test if Value is One, then do this. If Two is checked as well, then do something more.
Depending on situation you can use:
Convert string with delimiter to table (you can use this as subquery):
select regexp_substr('1:2:3','[^:]+', 1, level) ID from dual
connect by regexp_substr('1:2:3', '[^:]+', 1, level) is not null;
ID
--
1
2
3
Check one value using instr:
where instr('1:2:3', '2') > 0
If value of the second argument of the function is contained inside the first argument - function returns its position, otherwise - 0.
For performance I prefer the INSTR function, e.g. INSTR(':'||:p_item||':',':Two:') > 0

Resources