Can i use SUBSTR() inside of CAST() method? - mysql

I have a table called cities, with a column for timezones ( Timezone VARCHAR(10) NOT NULL that has timezones stored like: +00:00 or -02:00). - I am trying to select all cities that are two hours behind a city belonging to the +02:00 timezone.
I want to select the third character of the string and convert it to int. This is my approach:
SELECT CAST(SUBSTR(Timezone, 3, 1) AS INT)
FROM Cities;
My query returns error 1064. I cannot figure out why the syntax of my code is not correct. How can i solve this? Thank you!
SUBSTR(Timezone, 3, 1) returns the character that i want to modify. I do not want to replace it with 0, even if it would be easier, because having the posibility to do arithmetic operation with that number can help me reuse the code in future queries.

You need UNSIGNED (not INT) for CAST a numeric string as INTEGER
set #timezone ='+00:00';
SELECT CAST(SUBSTR(#Timezone, 3, 1) AS UNSIGNED)
and
SELECT CAST(SUBSTR(Timezone, 3, 1) AS UNSIGNED)
FROM cities

Related

Min function returning max valu and Max function returning min value

I have a table "abcd" with column name as "avg" and values "100" and "83".
When I try
select max(avg) from abcd -- Returns 83
select min(avg) from abcd -- Returns 100
seems quite weird to me. I have never imagined that I will be posting something like this in SO. It might be a minor thing to look but it's kicking my day out to solve it.
Am using MySQL and phpMyAdmin
Sounds like a string. A simple solution is to turn it to a number:
select max(avg + 0)
This uses "silent conversion", so it will not raise an error if the value is not numeric.
A better solution might be to turn it into an actual number in the data:
alter table t modify column avg int;
(The values appear to be integers.)
change the datatype of your column avg
if you using varchar its give wrong output on number function
using below query alter the column
ALTER TABLE `abcd` CHANGE `avg` `avg` INT(11) NOT NULL;
OR try this
SELECT max( cast(avg as unsigned) ) as avg FROM `abcd`
SELECT min( cast(avg as unsigned) ) as avg FROM `abcd`

'SUM' is not a recognized built-in function name when converting VARCHAR to DECIMAL

I am new to the community so please bear with me. I am working on a sum function that will take the values of 3 columns (Exchange, Commission, Otherfees) and give me that total based on row. The datatypes for these 3 fields are VARCHAR. I started by using a CONVERT function and then addressed any NULLs. Please see the query below:
SELECT SUM(
(SELECT(SELECT
CONVERT(decimal(18,4), isnull(ExchangeFee,0)) AS decimal
FROM T_TABLE) as EXCHANGE_VALUE) +
(SELECT(
SELECT
CONVERT(decimal(18,4), isnull(Commission,0)) AS decimal
FROM T_TABLE) AS COMMISSION_VALUE) +
(SELECT(
SELECT
CONVERT(decimal(18,4), isnull(OtherFees,0)) AS decimal
FROM T_TABLE) AS OTHERFEES_VALUE) AS decimal) AS SUMMED_VALUE
When running this query, I get the message
'SUM' is not a recognized built-in function name.
Please let me know your thoughts.
You could start by using the correct data types for your fields.
ExchangeFee, Commission and OtherFees are all numeric, so why store them in a varchar?
If the values should never be NULL, and here these look like they probably probably shouldn't, set them as NOT NULL and default them to 0.
That said, mysql will convert strings to numbers in a numerical context so you only need to worry about any NULL values which COALESCE or IFNULL will deal with.
As for the query which you want to sum the rows, all of the data is coming from T_TABLE so the general structure of the query should be:
SELECT COALESCE(ExchangeFee,0) + COALESCE(Commission,0) + COALESCE(OtherFees,0) AS SUMMED_VALUE
FROM T_TABLE;

Why is CAST function returning first value in comma-separated values, but not zero?

When I executed following query to find the country name by the ID, I accidentally passed a string that contained comma-separated values.
SELECT * FROM country WHERE id='6,AU,+61'
This query fetched that respective row.
When I tried casting this string into UNSIGNED using
SELECT CAST('6,AU,+61' AS UNSIGNED)
It returned 6, the first value.
When I tried integer values separated by comma (for eg: '7,8'), it also returned 7. So, it wasn't taking any values after the first comma.
In case of CAST('AU,+61' AS UNSIGNED), it returned zero.
Isn't '7,8' a string, so why is it not converting this into zero and taking first value instead?
MySql casts string to number by looking at the string from its left most char going right.
If the first char is a digit, it will iterate right until it reaches a non-digit char and will cast it to a number. if the string starts with a non-digit char it will cast to 0.
Thats why CAST('AU,+61' AS UNSIGNED) is 0
While CAST('7,8' AS UNSIGNED) is 7
However, The above is not documented specifically in the MySql Cast reference.
Although there are few examples over there and a specific line that implies such a behavior:
there are many different strings that may convert to the value 1, such as '1', ' 1', or '1a'.
However this can be validated with few simple tests:
SELECT CAST('a7' as UNSIGNED) as 'col_a7'; -- 0
SELECT CAST('7q6' as UNSIGNED) as 'col_7q6'; -- 7
SELECT CAST(' 7q6' as UNSIGNED) as 'col__7q6'; -- 7
SELECT CAST('1.4' as UNSIGNED) as 'col1.4'; -- 1
I might not be so clear in my description above, but these tests should clarify things.

Date Range in RazorSQL

How to display results with date range?
For example:
I want to show results for sept. 15, 2011 to oct. 20, 2011?
Thanks
This has little to do with RazorSQL and almost everything to do with the data that you're querying. Does the data set that you are querying have a date column that you can key off of? If so, you have two options.
Use a where clause in your SQL query to only bring back data from your source database that is within the range that you want.
Retrieve all of the data in a table and then use RazorSQL's filter feature to whittle down the data.
Of course, from a performance perspective, the first option is the best.
try this hope it will help you
select * from urtable where cast (DATEPART(year, datatimeclm) as varchar(50))+'-'+cast (DATEPART(month, datatimeclm)as varchar(50))+'-'+ cast (DATEPART(day, datatimeclm)as varchar(50)) between '2011-09-15' and '2011-10-29'
For SQL-Server try this
DECLARE #tbl table(dtm datetime)
insert into #tbl
values ('20110914 00:59:00'),
('20110915'),
('20110915 05:10:00'),
('20110916 05:10:00'),
('20111029 05:10:00'),
('20111029'),
('20111030')
SELECT *
FROM #tbl
WHERE dtm>='20110915' AND dtm<'20111030'
To return date without time from a datetime value you can use this CONVERT(datetime,CONVERT(varchar,#date,1),1)
In SQL SERVER 2008 + you can use DATE data type in that case you could use dtm<='20111029'.

mysql - difference between two integer column doesn't works as expected

I'm run this query:
SELECT id,like - dislike as result
FROM mytable
Where the column like and dislike are unsigned integer. If the column dislike is greater than like mysql return number like 18446744073709551596, so seem that mysql treat this like unsigned and can't return negative number but continue the computation from a sort of MAX_UNSIGNED_INT. How can I have the correct result
Try casting the two values (or maybe only on of them)
SELECT id, convert(like, SIGNED ) - convert(dislike, SIGNED ) as result
FROM mytable
or only the result
SELECT id, convert(like - dislike, SIGNED ) as result
FROM mytable
In the first way you can get type overflow! The Second way is better, but I'm not sure it works with mysql.
You could try casting them as Int:
SELECT id, CAST(like AS INT) - CAST(dislike AS INT) as result FROM mytable