ISNULL with multiple Integer values in SQL Server - sql-server-2014

My requirement is to pass input parameter with some Integers into DB to fetch the data. But in the front end, I'm checking if we didn't select any input data (Report type of application), NULL should pass else all the data or selected data should pass.
WHERE
a.DateTime BETWEEN '2018-04-12 00:00:00' AND '2018-04-12 23:59:59'
AND ISNULL('0000441183344450,0000447769267501,0000447789917187',CallNumber) = CallNUmber
AND ISNULL(CAST('1,2,3' AS INT), ID) = ID
In the above query ISNULL(CAST('1,2,3' AS INT), ID) = ID is causing an error:
Conversion failed when converting the varchar value '1,2,3' to data type int
I know its very generic error but my requirement is to pass the selected Integer values or all values if the user didn't select any values in the input.
In the database, ID has an int datatype and if used with quote values (and ISNULL('121','122',AgentSkillTargetID)=AgentSkillTargetID) I'm getting an error
The isnull function requires 2 argument(s)
In the same query
ISNULL('0000441183344450,0000447769267501,0000447789917187',CallNumber) = CallNUmber
is working, since the datatype of CallNumber is varchar.

The isnull function is a t-sql function that can only accept two parameters. For returning the first non-null value from a larger list of parameters, use the ansi-complient coalesce function instead. Some people might claim you should never use isnull, since it's not ansi complient. Personally, I don't think that it's a good enough reason. I think you should use the best tool available.
For more information, read the Comparing COALESCE and ISNULL section of the coalesce doc page.

Related

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.

min/max functions with date return result with VARCHAR datatype instead of TIMESTAMP

I faced the issue related to min/max functions with a date.
For example - I get Varchar result datatype when querying min(Timestamp(dateColumn)), but I need Timestamp result datatype, I checked these functions with many different functions inside and it returns Varchar always, in every case except when I just call min(dateColumn). In the application I can't cast this operation every time, how could I cope with it?
I have tried to get a date from jdbc ResultSet but I can't track when I have to use result.getTimesatamp. It is impossible to track it.
I expect the min(timestamp('2019-01-01')) or max(timestamp('2019-01-01')) result with Timestamp/Date datatype, but actual result is Varchar result datatype.
Example - SELECT MIN(TIMESTAMP(orders.OrderDate)) FROM orders
The result will be with varchar datatype, but I need the timestamp.
Querying in workbench, dbeaver - results are the same
It is a bug in MySQL. You can do:
select max(x)
from (
select timestamp(now()) as x
) as x;
Or just use:
select min(dateColumn)
as use of the timestamp()-function is unnecessary in the query.

SQL ignoring string in where condition

Why if I run a query with gibberish at the end of the where condition it incorrectly returns a result.
Example:
SELECT * FROM contractor_table WHERE contractorID = '97sd'
I am getting the row with the ID 97, when I should get no result.
What is happening here is that you are comparing the contractorID column, which is integer or some other numeric type, against a string literal 97sd. This doesn't make any sense, so MySQL, based on its casting rules, attempts to first cast 97sd to an integer. Consider the result of the following query:
SELECT CAST('97sd' AS unsigned);
In fact, this outputs just 97, the integer. So, in practice this means that the "gibberish" at the end of your string literal, which begins with an integer, will be ignored by MySQL.
But best practice here is to always compare columns against the correct literal types. So use the following version always, for best results:
SELECT * FROM contractor_table WHERE contractorID = 97;
This happends when you have column type int or other numeric if you convert it into varchar than it will retun no output

MySQL comparing 2 DATETIME values of unknown type

It sounds simple but I'm stuck. What I want is to be able to compare two MySQL DATETIME values but due to the open ended nature of how the queries are formed I do not know the datatype of value 1 or value 2. For instance, each value can either be a string that is input by an end user, a date field or a DATETIME field.
Example:
dateTime1 > 1/18/2017 2:30pm
The issue I'm running into is STR_TO_DATE() expects a string and returns null with DATETIME, DATE_FORMAT() expects a date and returns null with a string. I need a function or nested group of functions that will give me the same result regardless of the value of the datatype & would like to address directly in mysql rather than pre-processing or making the user input validation stricter. I used to use CAST(value, DATETIME), however CAST() doesn't read the date correctly in the more recent versions of MySQL (it ignores the am/pm specification). Any ideas?
GREATEST() did not work for me as it would always return null if any component was null, however it led me to COALESCE() which provides me with the solution I am looking for as it returns the first non NULL value. It makes the assumption the value will always be DATE, DATETIME, or a date time string which is the case for my issue:
SELECT COALESCE(STR_TO_DATE(value1, '%c/%e/%Y %r'), value1) > COALESCE(STR_TO_DATE(value2, '%c/%e/%Y %r'), value2)
Note: value1 and value2 are either DATE / DATETIME columns or date time string values
You can consider using the coalesce() function, with a list of different formats used with str_to_date(). coalesce() will ignore any null from the list (but at least one of them should be non-null, or you still get a null).
select
coalesce(
str_to_date('13/18/2017 2:30pm', '%m/%e/%Y %l:%i%p') -- will get a null
, str_to_date('18/13/2017 2:30pm', '%e/%m/%Y %l:%i%p') -- will get a null
, str_to_date('18/01/2017 14:30', '%e/%m/%Y %k:%i')
) as answer;
The code may be brittle, because there are so many different date/time formats that a human user may input.
You may also need to be very familiar with all the different format characters that str_to_date() take. See this manual page for more details:
https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-format
Updated
An earlier version of this answer incorrectly suggested the use of the greatest() function.

Check the value type of a JSON value in Postgres

Let's say I have a json column fields, like so:
{phone: 5555555555, address: "55 awesome street", hair_color: "green"}
What I would like to do is update all entries where the json key phone is present, and the result is of type number to be a string.
What I have is:
SELECT *
FROM parent_object
WHERE (fields->'phone') IS NOT NULL;
Unfortunately this still returns values where phone:null. I'm guessing that a JSON null is not equivalent to a SQL NULL.
How do I
1) How do I rule out JSON nulls
AND (fields->'phone') <> null produces
LINE 4: ...phone') IS NOT NULL AND (fields->'phone') <> 'null';
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
2) Check the type of the value at that key, this pseudocode (type_of (fields->'phone') == Integer) but in working PGSQL.
3) Modify this to update the column
UPDATE parent_object
SET fields.phone = to_char(fields.phone)
WHERE query defined above
As other folks have said, there is no reason to convert the variable to an integer just to them cast it to a string. Also, phone numbers are not numbers. :-)
You need to be using the ->> operator instead of ->. That alongside IS NOT NULL gets your SELECT query working.
Note the difference between the two tuple values after running this query:
SELECT fields->'phone', fields->>'phone'
FROM parent_object;
Your working query:
SELECT *
FROM parent_object
WHERE (fields->>'phone') IS NOT NULL;
Postgres does not currently natively support atomically updating individual keys within a JSON column. You can write wrapper UDFs to provide this capability to you: How do I modify fields inside the new PostgreSQL JSON datatype?
For checking the type of the value at key, postgres has the following in the documentation.
json_typeof ( json ) → text
jsonb_typeof ( jsonb ) → text
Returns the type of the top-level JSON value as a text string. Possible types are object, array, string, number, boolean, and null. (The null result should not be confused with a SQL NULL; see the examples.)
json_typeof('-123.4') → number
json_typeof('null'::json) → null
json_typeof(NULL::json) IS NULL → t