Weird Select Result - sql

I have a table with an ID field of INT Type.
I am doing some data validation and noticed that
SELECT * from mytable where id=94
and
SELECT * from mytable where id='94'
works perfectly, but if I use
SELECT * from mytable where id='94dssdfdfgsdfg2'
it gave me the same result! How is this possible?

it would be possible if the internal implementation of MySql's string to int function dropped all characters from the string after the first non-numeric when parsing it.

What you've witnessed is called "implicit data conversion".
Implicit, the opposite of "explicit", means that the data type is automatically converted to the data type of the column being compared when possible. In this case, MYTABLE.id is an INTeger data type so MySQL will convert the value being compared to an INT if it is enclosed in single quotes (string based data type to SQL).
Because of the conversion, the data is getting truncated at the end of the last numeric character after starting from the leftmost position in the string.

Related

Conditional casting of column datatype

i have subquery, that returns me varchar column, in some cases this column contains only numeric values and in this cases i need to cast this column to bigint, i`ve trying to use CAST(case...) construction, but CASE is an expression that returns a single result and regardless of the path it always needs to result in the same data type (or implicitly convertible to the same data type). Is there any tricky way to change column datatype depending on condition in PostgreSQL or not? google cant help me((
SELECT
prefix,
module,
postfix,
id,
created_date
FROM
(SELECT
s."prefix",
coalesce(m."replica", to_char(CAST((m."id_type" * 10 ^ 12) AS bigint) + m."id", 'FM0000000000000000')) "module",
s."postfix",
s."id",
s."created_date"
FROM some_subquery
There is really no way to do what you want.
A SQL query returns a fixed set of columns, with the names and types being fixed. So, a priori what you want to do does not fit well within SQL.
You could work around this, by inventing your own type, that is either a big integer or a string. You could store the value as JSON. But those are work-arounds. The SQL query itself is really returning one "type" for each column; that is how SQL works.

PostgreSQL - casting varchar to int?

I'm trying to execute the following query:
DELETE FROM table_name WHERE ID>9;
But i can't since the 'ID' field is of type 'varchar'.
How can i cast it to 'int' and have it act properly? (deleting all rows with ID greater than 9 rather than converting it to a numeric varchar value)
I don't know why you would store a numeric value as a string. You might want something more like:
DELETE FROM table_name
WHERE regexp_matches(ID, '^[1-9][0-9]');
This will delete from the table any id that starts with two digits, where the first is not 0. If you attempt a conversion, then you might get a conversion error if not all ids are numbers. This will also work for long numbers that would overflow an int (although numeric would fix that problem).
EDIT:
For a general solution, I think I would write it as:
where (case when regexp_matches(id, '^[0-9]+$')
then id::numeric
end) > 70000
The case should prevent any error on non-numeric ids.

Check if contents of TEXT column are purely numeric

I've got an Sqlite DB where the data looks purely numeric (integers) and the column is typed TEXT. I would like to type it as INTEGER if possible.
What query can check if every cell of a certain column can be successfully casted to INT?
SELECT * FROM table WHERE INT(column) != NULL
Alternatively I would like to check if the cells are numeric (don't have any letters/symbols)
SELECT * FROM table WHERE column NOT LIKE "%a-z%"
As a side note, I wanted to do this to reduce the size of the DB, but since Sqlite uses dynamic typing (per cell typing) would this have ANY effect on the size of the DB?
You have to check whether all values can be converted into an integer:
SELECT *
FROM MyTable
WHERE CAST(MyColumn AS INTEGER) IS NOT MyColumn;

Change SQL Field Data Type varchar to float with data already stored

I have an imported database which contain lots of float field.
When I imported it, all the float field converted to string and I need to convert it back.
I try alter table to change the data type but I keep getting error (even if the row is empty or null).
EDIT : The server is curently down so I can't get the error message at the moment. My DBMS is SQL Server.
you can do so if all data are really numeric type.
There may be some data which hv null --no problem here.
There may be some data which are blank(('') but not null--problem is because of this.
First you make a select query to retrieve all data which are blank
say,
Select * from table1 where col=''
now update these rows with null
update table1 set col=null where col=''
After this,I think you can easily convert it to float
References: error converting data type varchar column to float.
You can first add a new field in your table with datatype float and then update it using convert function:
UPDATE #tbl
SET
num = convert(FLOAT, text)
SELECT *
FROM
#tbl

Select string as number on Oracle

I found this odd behavior and I'm breaking my brains with this... anyone has any ideas?
Oracle 10g:
I have two different tables, both have this column named "TESTCOL" as Varchar2(10), not nullable.
If I perform this query on table1, i get the proper results:
select * from table1 where TESTCOL = 1234;
Note that I'm specifically not placing '1234'... it's not a typo, that's a dynamic generated query and I will try not to change it (at least not in the near future).
But, if I run the same query, on table2, I get this error message:
ORA-01722: Invalid number
Both queries are run on the same session, same database.
I've been joining these two tables by that column and the join works ok, the only problem shows whenever I try to use that condition.
Any ideas on what could be different from one table to the other?
Thanks in advance.
If TESTCOL contains non-numbers, then Oracle might run into problems when converting TESTCOL entries to numbers. Because, what it does internally, is this:
select * from table1 where TO_NUMBER(TESTCOL) = 1234;
If you're so sure that 1234 cannot be expressed as a VARCHAR literal, then try this instead, in order to compare varchar values, rather than numeric ones:
select * from table1 where TESTCOL = TO_CHAR(1234);
Well obvious TABLE2.TESTCOL contains values which are not numbers. Comparing a string to a numeric literal generates an implicit conversion. So any value in TESTCOL hich cannot be cast to a number will hurl ORA-1722.
It doesn't hit you where you compare the two tables because you are comparing strings.
So you have a couple of options, neiher of which you will like. The most obvious answer is to clean the data so TABLE2 hdoesn't contain non-numerics. Ideally you should combine this with changing the column to a numeric data type. Otherwise you can alter the generator so it produces code you can run against a shonky data model. In this case that means wrapping literals in quote marks if the mapped column has a character data type.
You are hitting the perils of implicit typecasting here.
With the expression testcol = 1234 you state that you want to treat testcol as a numeric column, so Oracle tries to convert all values in that column to a number.
The ORA-01722 occurs because apparently at least one value in that column is not a number.
Even though you claim that this is "not a typo" it indeed is one. It's a syntactical error.
You will have to declare your parameter as a string literal using single quotes: where testcol = '1234'
Creating a correct condition is the only solution to your problem.
The following should work. Just replace the "your where".
select *
from table1
where (select TO_NUMBER(TESTCOL)
from table2
where "your where") = 1234;