How to set JasperReports 5.6 Equal Clause Function to IS NOT NULL - mysql

I'm working with iReport Designer and JasperServer 5.6 on a MySQL database and I'm trying to make my report return all results when the parameter is null.
I've been looking at the documentation here: http://jasperreports.sourceforge.net/sample.reference/query/, which has been quite helpful except it doesn't have what I want. The closest I've gotten is here in the documentation:
The $X{EQUAL, column_name, parameter_name} clause function
The function expects three mandatory clause tokens:
The first token represents the function ID and always takes the fixed value EQUAL.
The second token is the SQL column (or column combination) to be used in the clause.
The third token is the name of the report parameter that contains the value to compare to.
If the parameter's value is not null, the function constructs a
= ? clause. If the parameter's value is null, the
function generates a IS NULL clause.
All the parameters I'm inputting are the id's of the records I'd like to see, so when I use this I get no results because an id or the Primary Key cannot be null.
Ex.
SELECT *
FROM User
WHERE $X{EQUAL, user.id, user_id}
Inputting 1 will return user id 1 and inputting nothing, or null, will return me nothing. What I want it to return instead is all users in the table.
Is there an easy fix to this problem, like having this function return IS NOT NULL when this happens? Is there something else in JasperServer or iReports that will help me or is there something I can do in SQL that will ignore a WHERE clause when I have this parameter set to null?

You can use the below logic in your query's WHERE clause to achieve what you are asking (this works in postgres, but it should work in MySQL as well):
where (($P{parameter1} is null) or (user.id = $P{parameter1}))
If the parameter is null the first part of the OR comparator will return true, and the query will ignore the rest of the expression, which should give you all users in the user table. If it is not null, it will skip over the first part and execute the query for the user.id passed to the parameter.
Hope this helps!

Related

Custom column in Oracle/SQL/My-Sql Query?

I have database ready with data as per below screenshot, green column is customized column which I need to generate while querying data from SQL/Oracle.
Logic: If Actual_Completion_Date is not an empty/null, then bring
Actual_Completion_Date into Completion_Date else get
Schedule_Completion_Date in Completion_Date column.
Is there any way, where I should write If statement while defining column names in SQL query without stored procedure help.
If both date field contains NULL value then use simply COALESCE(). IF first one is NULL then second one value will show if it's not NULL. If first one is not null then will sshow first one value.
SELECT Activity_Details, Actual_Completion_Date
, Schedule_Completion_Date
, COALESCE(Actual_Completion_Date, Schedule_Completion_Date) AS Completion_Date
FROM tbl;
You can simply do this in the SELECT clause of your query. For example using the IF() function like this in mysql:
SELECT Activity_Details, Actual_Completion_Date, Schedule_Completion_Date, IF(Actual_Completion_Date IS NOT NULL, Actual_Completion_Date, Schedule_Completion_Date) AS Completion_Date
FROM tbl;
The IF function takes a condition that should return True or False as the first argument. If the condition evaluates to true, the second argument is returned and if it evaluates to false, the third.
In Oracle or Microsoft SQL server you would do something similar in the SELECT clause of your query, but using CASE WHEN ... THEN ... ELSE ... END
Oracle (and MySQL) both support generated columns. That means that you can add the logic as part of the table definition. I'm not sure if this is what you are asking for, but in Oracle, this looks like:
alter table t add column completion_date date generated always as
(coalesce(Actual_Completion_Date, Schedule_Completion_Date)) virtual;
This would be calculated when the table is queried and available to any query that uses the table.

How Coalesce function deals with datatype

I am new to COALESCE function in REDSHIFT. I ran below four queries in mysql and Redshift.
1st and 2nd query executed as expected in both mysql and redshift. But for 3rd and 4th query I am getting two different results in mysql and Redshift. How does this behave?
select COALESCE(null,null,1) -> 1
select COALESCE(null,null,'John') -> 1
select COALESCE(null,null,1,'John') -> (Redshift : error , mysql:1)
select COALESCE(null,null,'John',1) -> (Redshift: error, mysql:John)
Also this query should give error in mysql but it has succeeded
Any help is appreciated
Amazon Redshift Database Developer Guide claims:
An NVL expression is identical to a COALESCE expression. NVL and
COALESCE are synonyms.
Syntax
NVL | COALESCE ( expression, expression, ... )
An NVL or COALESCE expression returns the value of the first expression
in the list that is not null. If all expressions are null, the result
is null. When a non-null value is found, the remaining expressions in
the list are not evaluated.
This type of expression is useful when you want to return a backup
value for something when the preferred value is missing or null. For
example, a query might return one of three phone numbers (cell, home,
or work, in that order), whichever is found first in the table (not
null).
If you obtain the error this may mean that the returned value datatype do not match the datatype of recordset field or any another structure which must accept the returned value.
PS. Will you show error messages?
Though it is not written in the documentation, but coalesce works on the compatible data types. Integer and varchar cannot be compared.
The error becomes more evident when you provide column name instead of hard-code values. Try executing this:
select coalesce(integer_column, varchar_column) from a_table;
You would get an error saying something like this:
coalesce types integer and varchar cannot be matched.

If one value is returned for a parameter then set as default, if more than one value is returned do not select a default

We have a series of reports which return a set of values for a parameter based on the userID. This works and we're happy with the way it works.
Now we need to implement a default parameter setting. The logic being
If there is only one value in the parameters available dataset, then set that as the default.
If there is more than one value in the parameters available dataset, then leave the parameter blank.
This is what I have so far - I know I have the following issues:
-Parameters cannot read fields, therefore I need the expression to look at the dataset as a whole.
-I'm unsure what my then statement should be to allow the user to review all available values without them being selected.
=IIf(CountDistinct(Fields!storekey.Value, "UserStoreVerification")) = 1, First(Fields!storekey.Value, "UserStoreVerification")," ")
You can create a separate dataset to populate the "default values" for the parameter. In this dataset you can add logic to count the number of rows that would be returned by the other dataset that provides the parameter values. If there are greater than 1 values returned by the first query then the second dataset just returns NULL (i.e. no default values are selected).
Example
If your original dataset for parameter values (e.g. "dsParamProduct") used a query like this:
SELECT ProductNumber
FROM dbo.Product
WHERE Available = 'Yes'
Then the dataset query for the default values (e.g. "dsParamProductDefault") could be something like this:
DECLARE #ValueCount INT
SELECT #ValueCount = COUNT(*)
FROM
(
SELECT ProductNumber
FROM dbo.Product
WHERE Available = 'Yes'
) vals
IF #ValueCount = 1
SELECT ProductNumber
FROM dbo.Product
WHERE Available = 'Yes'
ELSE
SELECT NULL
Supplying "NULL" as the default value when there is more than one value will mean none of the available values are selected and therefore the user will have to manually select them (assuming that NULL isn't a valid value for your parameter - if it is then make sure the default query will return something else that is definitely not valid). If there is only one possible value then the default value query just returns the same result as the parameter values dataset, which means that the parameter value will be selected.
Set up another parameter that is dependent on the first, same type but slightly different name, and do your code at bottom with one suggested change:. Change " " at the end before the parenthese end to be 'NOTHING' instead. I believe this is interpreted by SQL as NULL which is what you want.
Now you should be getting population of the parameter so I would debug and check it by just dragging and dropping it to the design surface and it should be black if you have more than one default value. You can optionally make this parameter 'hidden' once you can confirm it works.
Now you trick your main dataset with a nifty predicate (or else use some other logic if it suits you better)
Where value = isnull(#DependentParam, value)
Basically this is stating "if the parameter is not null use it, else equate the clause to be everything as it will assume value = value".

COALESCE() to get Not null as well as NULL Values

I have my Mysql Query as :
select RecordID,ID,Name,Description,RecordDateTimeUTC,Location from
eemployee where RecordID like ? and(isNull(RecordDateTimeUTC) OR RecordDateTimeUTC= CASE WHEN COALESCE(?,'') = '' THEN RecordDateTimeUTC ELSE ? END)........
Now my query There are lott of fields(? --> this is where i am putting my data for filter perpose) upon which user can query so i am using coalesce but the disadvantage of using coalesce is it doesn't give me null values when i want to get all data present in employee table , so to get null values i have used isNull function.
Now i am testing the above query for two use cases
1-->User can pass percentage in RecordID:-In this case he should get all data either null as well as not null values :
select RecordID,ID,Name,Description,RecordDateTimeUTC,Location from
eemployee where RecordID like '%'
and(isNull(RecordDateTimeUTC) OR RecordDateTimeUTC= CASE WHEN COALESCE('','') = '' THEN RecordDateTimeUTC ELSE '' END)
2-->User can filter data based on RecordDateTimeUTC:- If user passes this parameter then he should get all not null data satisfying the above filteration.:-
select RecordID,ID,Name,Description,RecordDateTimeUTC,Location from
eemployee where RecordID like '%' and(isNull(RecordDateTimeUTC) OR RecordDateTimeUTC= CASE WHEN COALESCE('2012-07-09 11:11:00','') = '' THEN RecordDateTimeUTC ELSE '2012-07-09 11:11:00' END)
For the first use case it is working fine but for the second use case it is giving me filtered data as well as null Data
So what should be my query so that both my use cases are supported by the above single query.
I am using MYSQl Query Browser to test my query
Thanks in advance
It looks like you're trying to make parameters optional while using a single static SQL statement. In that case I would imagine you mean something like:
SELECT RecordID,ID,Name,Description,RecordDateTimeUTC,Location
FROM eemployee
WHERE (#RecordId IS NULL OR RecordID LIKE #RecordId)
AND (#RecordDateTimeUTC IS NULL OR RecordDateTimeUTC = #RecordDateTimeUTC)
If the parameter value is NULL, it will be omitted completely from the filter, otherwise the passed value will be used.
Note you can't use ? here because of the need to re-use the parameter - unless you want to specify each parameter twice, that is. Specifying a name makes the query a lot more readable IMHO.

What does a WHERE clause of "sql was here" mean?

Can anyone help me understand or post any ideas concerning this where clause?
sql was here
I've changed the table name, but other than that, any idea what the developer was trying to do here?
There is nothing else after that, that's the where clause.
If (table.date_field = (select max(table2.exit_date) from table as table2)) is null the it'll return 1=1, which basically means there's no where clause at all.
Now let's look into that nasty expression. I can only assume that if "a = b" is not true then that's also equivalent to null, otherwise it seems like the first branch would always happen. It looks like it's trying to say "if the latest exit date is equal to the date field, select those, otherwise have no where clause". However, I don't think that this will work at all. It really looks like either way, each row will be selected.
The MySQL ifnull function returns the first argument if it is not null, otherwise the second argument. This looks like it tries to compare table.date_field to the max(table2.exit_date), and return true if the comarison was not possible due to nulls.
It looks to me like he is trying to find the row where table.date_field is equal to the maximum of table.exit_data. There is a check for null which I think would happen in any of these cases:
table is empty
all rows in table have exit_data set to NULL
table.date_field is NULL for the row in question
In any of these three cases, the row will be returned. I don't understand why he uses the string '1=1' instead of, to give some examples: 1=1, 1 or true, but it appears to work fine. In the first case I assume that there will be no rows in the result set anyway (depending on the rest of the query) so he was probably trying to handle one of the other two cases - I'd guess the last one.
This is only an explanation of what is happening. To understand why he is doing this, it would help if you gave a little more context.
MySQL is nonstandard in that true is really equal to the numeric value 1. Any expression that evaluates to true, or any nonzero value, satisfies the condition.
mysql> CREATE TABLE foo AS SELECT 1=1 AS f;
mysql> SHOW CREATE TABLE foo;
CREATE TABLE `foo` (
`f` INT NOT NULL DEFAULT '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
So the following WHERE clause is legal in MySQL, but not in most other SQL databases:
... WHERE 1;
Some people use 1=1 as a placeholder condition meaning true, but putting it in a string is meaningless because SQL expressions have no equivalent to an eval() function as other languages have. In this case, the leading character 1 in the string is implicitly cast to a numeric value 1, which is interpreted as true in MySQL. So it probably works as intended, but kind of by accident.
The use of IFNULL() is so that if either date_field or MAX(exit_date) is NULL, it returns the row. If you didn't use this function, then anything = NULL would evaluate as unknown, which means the row would not be returned.
It says basically if table.date_field = max exit date or if max exit_date is null or table.date_field is null return true. Will return false if max exit_date is not null and table.date_field is not null but they do not equal.