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.
Related
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.
Consider the following table:
SELECT id, Bill_Freq, Paid_From, Paid_To, Paid_Dt, rev_code FROM psr_20160708091408;
The requirement is to fetch the row which has rev_code populated with the string **SUM**.
I've also noticed that for every row with rev_code populated as **SUM** its Bill_Freq won't be either null or zero.
So I wrote two queries to fetch the row with the lowest id
Query based on string check in where clause:
select
min(id) as head_id,
bill_freq,
Paid_From,
Paid_To,
Paid_Dt
from
`psr_20160708091408` where rev_code = "**SUM**";
Query based on true condition:
select
min(id) as head_id,
bill_freq,
Paid_From,
Paid_To,
Paid_Dt
from
`psr_20160708091408` where bill_freq;
I haven't seen anyone use the second type, would like to know its reliability and circumstance of failure.
If by "second type" you mean a where clause with no explicit condition, then there is a good reason why you do not see it.
The SQL standard -- and most databases -- require explicit conditions in the where. MySQL allows the shorthand that you use but it really means:
where not billing_freq <=> 0
or equivalently:
where billing_freq <> 0 or billing_freq is null
(The <=> is the null-safe comparison operator.
The more important issue with your query is the min(). I presume that you actually want this:
select p.*
from psr_20160708091408 p
where rev_code = '**SUM**'
order by id
limit 1;
Also, you should use single quotes as string delimiters. That is the ANSI standard and there is rarely any reason to use double quotes.
Actually you can use the second type of query, but as your requirement is based on rev_code, it is always good to have condition with rev_code, because of 2 reasons
Bill_Freq having no NUlls or Zeros might be assumption based on current data
Even if it is true, in future, your application logic might change and it might have a scenario having NULL or zero, which will break your logic in future.
So my suggestion is to use first query with Rev_code
Please try to use below query
select
id,
bill_freq,
Paid_From,
Paid_To,
Paid_Dt
from
`psr_20160708091408` where rev_code = "**SUM**" ORDER BY ASC LIMIT 0,1;
Thanks.
The requirement says it itself.
The requirement is to fetch the row which has rev_code populated with
the string '**SUM**'
In the scenario that bill_freq IS NOT NULL and rev_code is populated with
the string '**SUM**' then your logic will obviously fail.
Go for
where rev_code = "**SUM**";
I am using DLAST to return a specific field value for the last record. The issue I am having is that the last record isn't always the newest date record. I need to return the value of a specific field for the newest date record.
You can't depend on DLast() to return a value from the "last record" of a table unless you use a query based on the table and indicate how the rows should be ordered. From the Application.DLast Method help topic ...
NoteIf you want to return the first or last record in a set of records (a domain), you should create a query sorted as either
ascending or descending and set the TopValues property to 1.
If you want to use DLast(), create a query and use the query name as the domain argument. For example, with this as Query1 ...
SELECT ASSY
FROM L2_AOI1
ORDER BY [your date field];
... this should work as the text box's Control Source ...
=DLast("ASSY", "Query1")
However, you could use a different query which returns the most recent ASSY and use DLookup with that query. For example, with Query2 ...
SELECT TOP 1 ASSY
FROM L2_AOI1
ORDER BY [your date field] DESC;
=DLookup("ASSY", "Query2")
Either way, include an index on [your date field] to optimize performance.
You can also use DLookup directly with an SQL clause:
=DLookup("Assy", "L2_AOI1", "[YourDateField] = (Select Max([YourDateField]) From L2_AOI1)")
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!
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.