Stop concat removing leading 0 - sql

Hoping someone can help.
I am attempting to add a ||'m' to my query but when I add the concat it removes the leading zero.
With out the ||'m' I get this result:
0.00
With the concat I get this result for example:
.0m
edit:
Here is the query:
round(MAX(city_longitude),1) - round(MIN(city_longitude),1)||'m'
Cheers

Try wrapping the whole ROUND statement in a TO_CHAR giving it a format mask.
TO_CHAR(round(MAX(city_longitude),1) - round(MIN(city_longitude),1), '0.00')||'m'
This way you effectively concatenate a string with a string whereas you are currently concatenating a numeric with a string forcing an implicit conversion.
Implicit conversions are usually frowned upon as they can lead to unexpected results.
Oracle says:
Oracle recommends that you specify explicit conversions, rather than
rely on implicit or automatic conversions, for these reasons:
• SQL statements are easier to understand when you use explicit
datatype conversion functions.
• Implicit datatype conversion can have a negative impact on
performance, especially if the datatype of a column value is converted
to that of a constant rather than the other way around.
• Implicit conversion depends on the context in which it occurs and
may not work the same way in every case. For example, implicit
conversion from a datetime value to a VARCHAR2 value may return an
unexpected year depending on the value of the NLS_DATE_FORMAT
parameter.
• Algorithms for implicit conversion are subject to change across
software releases and among Oracle products. Behavior of explicit
conversions is more predictable.
Number formats are here:
http://www.oradev.com/oracle_number_format.jsp
Hope it helps...

Related

ORA-01722 invalid number on different numbers?

I have a condition in a query:
ABS ( FIB.QUANT1 ) = ( OI.KLINE * :intv1000 ) / 1000.000000
when I run the query with intv1000 = 1000000 - query runs ok.
when I run the query with intv1000 = 1000 I get ORA-01722 (not immediately, after about 5-6 seconds).
Any Idea why ?
QUANT1 - NUMBER(16,2)
KLINE - NUMBER(38)
The condition is self generated from the application, So I can't really change it.
Thank you
The ORA-01722 is an invalid number error.
You would get this error when a non-number -- typically a string -- has to be converted to a number. For example here.
This conversion can occur in many different ways although the three most common are:
to_number()
cast()
implicit conversion
The expression you have highlighted may or may not have anything to do with where the error actually occurs. What it is saying is that:
When :intv1000 = 1000000 then the row(s) with the problem data are filtered out.
When intv1000 = 1000 then the row(s) with the problem data are being processed.
Arrggh. This is very hard to determine. I would suggest starting by looking at the query and finding all explicit conversions to see if they are a problem.
If you find no back data, then you need to resort to looking at all comparisons (including joins), arithmetic expressions, and function calls to find the problem.
In general, I strongly recommend avoiding implicit conversion. Use explicit conversion to avoid such problems! Note: I do make an exception for conversion to strings with string functions and operators. These are usually pretty safe.

Hive dates: date 'yyyy-MM-dd' vs. 'yyyy-MM-dd' What is the difference?

What is the difference between referring to a hive date as date '2020-08-25' vs. just '2020-08-25' without the word date? Is it two different data types? or are these the exactly the same. This something I might put into a where statement like below:
where somedate<=date'2020-08-25'
vs.
where somedate<='2020-08-25'
date'2020-08-25' is a standard date literal: it generates a legitimate value of the date datatype.
On the other hand, '2020-08-25' is a literal string (that represents a date, but it could be anything else).
Now what is the best pick for the predicate in your where clause? It depends on the datatype of the column you want to compare.
If you have a date column, then I would recommend using a literal date. Otherwise, you rely on the ability of the database to understand what you mean, and implicitly convert the string to a date. Each database has its own set of rules to handle such case: in the worst case scenario, it might take the wrong decision and decide do string comparison, which would require converting all stored values to string (this depends on the database specification) - which would kill the performance of the query.
If you happen to be storing dates as strings (which usually indicates a bad design), then string comparison is fine.
date '2020-08-25' is a literal of type DATE.
'2020-08-25' - is a string literal.
String and dates can be implicitly converted, so both your where clauses are functionally identical. Depending on column datatype, implicit conversion may happen. Better use the same type to avoid implicit conversion.
Also DATE can be packed in 4 bytes integer in binary formats. See HIVE-3910

Oracle Implicit Conversion of String to date?

I work in T-SQL but have been given some Oracle PL-SQL for review on a Project.
Within the code there are Multiple WHERE clauses that do comparison of a Field of DataType = DATE against Strings which hold a "date".
ex:
WHERE to_date(mytable.mydatefield) > '23-OCT-2015'
OR
WHERE mytable.mydatefield > '23-OCT-2015'
Q1: Since "mydatefield" is already defined as a DATA type, isn't doing a "to_date" unnecessary?
Q2: Will Oracle do an implicit conversion on the '23-OCT-2015' and convert it to a date for comparison? I seem to remember encountering this before and comparing DATES to STRINGS caused issues?
Am I incorrect about that? If not can someone give me an example that I can use as evidence that it would not work?
A1: In general yes, but take the way Oracle handles implicit type conversions into account. The To_Date function around the mydatefield column expects a string input, so Oracle implicitly converts mydatefield to a string with a format matching the NLS_DATE_FORMAT session setting (which defaults to DD-MON-RR). Once converted to a string the To_Date function then converts it back to a date again using the current NLS_DATE_FORMAT setting. The newly reconstituted date is then compared to the string '23-OCT-2015', but since dates and strings aren't directly comparable the string value gets implicitly converted to a date using the current NLS_DATE_FORMAT setting. Depending on the value of the NLS_DATE_FORMAT setting, the first implicit conversion is likely to lose information specifically any time portion AND the original century, since the default NLS_DATE_FORMAT uses only a two digit year RR and no time component.
A2: Possibly, but it's best not to rely on it.
Both relations are poor programming for a couple of reasons. First they both are affected by implicit type conversions from dates to strings (or vice versa). Second they are both attempting to compare dates with strings in a non canonical form. As such 10-DEC-15 is less than 23-OCT-2015 because 1 is less than 2. Also note the difference in the number of digits representing the year since the default NLS_DATE_FORMAT uses a two digit year.
The correct method would be to compare the date column (possibly truncated) to a date string explicitly converted to a date
WHERE mytable.mydatefield > TO_DATE('23-OCT-2015', 'DD-MON-YYYY')
OR with truncation:
WHERE trunc(mytable.mydatefield) > TO_DATE('23-OCT-2015', 'DD-MON-YYYY')
which removes the time component of the date field.
Q1: According to Oracle, the first parameter of to_date() is a char value. Using it like to_date(date_value) you will force an implicit cast of date_value to char and then wrapping it again in a date value.
Q2: The server will do an implicit conversion from the string '23-OCT-2015' to a date value but based on database parameters which can differ from various servers(DEV vs PROD for example) so you should not rely on them. An example of correct usage would be WHERE mytable.mydatefield > to_date('23-OCT-2015','dd-MON-yyyy')
You should always use to_date/to_char to make sure you are using the correct format. Please see this answer for a more detailed explanation: Comparing Dates in Oracle SQL

Implicit casting when joining fields of different types

I am joining a field that has single digit numbers formatted with a leading 0 to another that does not have leading 0's. When I realized this I tested my query out only to find that it was actually working perfectly. Then I realized what I'd done... I had joined an nvarchar field to an int field. I would have thought sql would have given me an error for this but apparently it converts the character field to an int field for me.
I realize this is probably not a good practice and I plan to explicitly cast it myself now, but I'm just curious if there are rules for how SQL decides which field to cast in these situations. What's to keep it from casting the int field to a character type instead (in which case my query would no longer work properly)?
There are rules indeed.
CAST and CONVERT (Transact-SQL) to learn what can be converted to what ("Implicit Conversions" section).
Data Type Precedence (Transact-SQL) to learn what will be converted to what unless specifically asked.

T-SQL Cast versus Convert

What is the general guidance on when you should use CAST versus CONVERT? Is there any performance issues related to choosing one versus the other? Is one closer to ANSI-SQL?
CONVERT is SQL Server specific, CAST is ANSI.
CONVERT is more flexible in that you can format dates etc. Other than that, they are pretty much the same. If you don't care about the extended features, use CAST.
EDIT:
As noted by #beruic and #C-F in the comments below, there is possible loss of precision when an implicit conversion is used (that is one where you use neither CAST nor CONVERT). For further information, see CAST and CONVERT and in particular this graphic: SQL Server Data Type Conversion Chart. With this extra information, the original advice still remains the same. Use CAST where possible.
Convert has a style parameter for date to string conversions.
http://msdn.microsoft.com/en-us/library/ms187928.aspx
To expand on the above answercopied by Shakti, I have actually been able to measure a performance difference between the two functions.
I was testing performance of variations of the solution to this question and found that the standard deviation and maximum runtimes were larger when using CAST.
*Times in milliseconds, rounded to nearest 1/300th of a second as per the precision of the DateTime type
CAST is standard SQL, but CONVERT is only for the dialect T-SQL. We have a small advantage for convert in the case of datetime.
With CAST, you indicate the expression and the target type; with CONVERT, there’s a third argument representing the style for the conversion, which is supported for some conversions, like between character strings and date and time values. For example, CONVERT(DATE, '1/2/2012', 101) converts the literal character string to DATE using style 101 representing the United States standard.
Something no one seems to have noted yet is readability. Having…
CONVERT(SomeType,
SomeReallyLongExpression
+ ThatMayEvenSpan
+ MultipleLines
)
…may be easier to understand than…
CAST(SomeReallyLongExpression
+ ThatMayEvenSpan
+ MultipleLines
AS SomeType
)
CAST uses ANSI standard. In case of portability, this will work on other platforms. CONVERT is specific to sql server. But is very strong function. You can specify different styles for dates
You should also not use CAST for getting the text of a hash algorithm. CAST(HASHBYTES('...') AS VARCHAR(32)) is not the same as CONVERT(VARCHAR(32), HASHBYTES('...'), 2). Without the last parameter, the result would be the same, but not a readable text. As far as I know, You cannot specify that last parameter in CAST.