Convert Character to Number in Oracle - oracle

I have ColumnA in table. The data of each row is single character between A & H.
I want my select query to return 1 for 'A', 2 for B .... 8 for H.
My query always returns only one row. I can make a lookup table.
Anyone has better ideas to achieve the same ?

SELECT 1 + ASCII(columnA) - ASCII('A')
FROM table

Related

Merge with dual not working in 12c

Hi I am using Oracle 12c and I have executed the below query which returns 0 rows merged. Please advise if I am doing something wrong.
The table cons_temp contains two columns,
name, value.
merge into cons_temp tb
using (select 'Freez' as NAME, 'NOI' as VALUE from dual where 1=2) v
on (tb.NAME=v.NAME)
when matched then update set tb.VALUE=v.VALUE
when not matched then insert (NAME,VALUE) values(v.NAME, v.VALUE);
Why have you put this line in the USING query?
where 1=2
That will always evaluate to false (because 1 != 2). Consequently your USING query will return zero rows, so there is nothing to match or unmatch.
If you remove that WHERE clause your statement will do something.

Understanding the behavior of dbms_random.value in where clause

I have a table with two columns(Using oracle 11g database) : Country, IndexNumber. Table contains 10 rows(10 different cities and with its unique index number.)
For example:
Country IndexNUmber
India 1
Australia 2
. .
. .
. .
. .
US 10
Now i want to fetch a random row from above table by generating random number using dbms_random.value(1,10). To achieve that i am using below query:
select * from tab_name where indexnumber = dbms_random.value(1,10);
I am not able to understand the output of this query as some time it is fetching one row, some time zero rows and some time more that one row.
Can someone please make me understand how oracle is evaluating this query.
Thanks
Ankit
Since dbms_random.value is a nondeterministic PL/SQL function, it will be called once for each row evaluated by the query.
The function might return 4 when evaluating the first row, then it might return 8 on the second row, etc.
To compare each row to a single random number, you can turn the function call into a scalar subquery, e.g.:
select * from tab_name where indexnumber = (select dbms_random.value(1,10) from dual);
Since the subquery is not correlated to the main query, Oracle will execute it only once (for the first row returned from the table) and remember the result for all subsequent rows. In particular, if a suitable index is on indexnumber the query will be able to use it more efficiently since it knows it is probing for a single value.
When you run your original query:
select * from tab_name where indexnumber = dbms_random.value(1,10);
it appears that the call to dbms_random is happening for each record's where clause. In other words, there is a chance that every record in your table might be returned if the random number chosen happen to match the index for every record. If you want to retrieve a single random record, then follow this pattern:
select *
from
( select * from tab_name order by DBMS_RANDOM.VALUE )
where rownum < 2;

Is it possible to disaggregate in hive sql? [duplicate]

I'm trying to find a way to split a row in Hive into multiple rows based on a delimited column. For instance taking a result set:
ID1 Subs
1 1, 2
2 2, 3
And returning:
ID1 Subs
1 1
1 2
2 2
2 3
I've found some road signs at http://osdir.com/ml/hive-user-hadoop-apache/2009-09/msg00092.html, however I wasn't able enough detail to point me in the direction of a solution, and I don't know how I would set up the transform function to return an object that would split the rows.
Try this wording
SELECT ID1, Sub
FROM tableName lateral view explode(split(Subs,',')) Subs AS Sub
SELECT ID1, new_Subs_clmn
FROM tableName lateral view explode(split(Subs,',')) Subs AS new_Sub_clmn;
I was initially confused with the names used, sharing the above query thinking it would be of help.

Substring inside string

Suppose this is my table:
ID STRING
1 'ABC'
2 'DAE'
3 'BYYYYYY'
4 'H'
I want to select all rows that have at least one of the characters in the STRING column somewhere in another row's STRING variable.
For example, 1 and 2 have an A in common and 1 ad 3 have a B in common, but 4 does not have any characters in common with any of the other rows. So my query should return only the first three lines.
I don't need to know with which line it matched.
Thanks!
#A.B.Cade : Good solution but could be done without any distinct nor join.
SELECT * FROM test t1
WHERE EXISTS
(
SELECT * FROM test t2
WHERE t1.id<>t2.id AND
regexp_like(t1.string, '['|| replace(t2.string, '.[]', '\.\[\]')||']')
)
The query won't compare the string with extra rows since it'll stop the comparison as soon as 1 match is found for the current row...
See fiddle.
#GolezTrol's answer is a good one, but here is another approach:
select distinct t1."ID", t1."STRING"
from table1 t1, table1 t2
where t1."ID" <> t2."ID"
and regexp_like(t1."STRING", '['|| t2."STRING"||']')
First take a cartessian product of the table
Then make sure your not comparing the same string to itself
then create a regexp from one string for comparing to the other - [<string1>] means that the string must contain one of the letters in the [ ] which are all from string1
Here is a fiddle
Like this:
select distinct
id, name
from
(select distinct
x.id,
x.NAME,
length(x.NAME) as leng,
substr(x.name, level, 1) as namechar
from
YourTable x
start with
level = 0
connect by
level <= length(x.name)) y
where
exists
(select
'x'
from
YourTable z
where
instr(z.name, y.namechar) > 0 and
z.id <> y.id)
order by
id
What it does:
First, (inner select) use the table with a number generator that returns a number for each letter in the name. Now each record in YourTable is returned Length(Name) times, each with another number. That generated number is used to isolate that letter (substr).
Then (subselect in top level where clause) check if records exist that contain that isolated letter. Distinct is needed, because records are returned more than once if more than one letter matches. You could add namechar to the outer select field list to see the letter that match.

Update One table Column with Values from Another table Having Similar

Hi Guys I have Two tables (MIGADM.CORPMISCELLANEOUSINFO and CRMUSER.PREFERENCES) and Each Has a field called PREFERENCE_ID and ORGKEY. I want to Update the Preference ID for MIGADM.CORPMISCELLANEOUSINFO with Preference_ID from CRMUSER.PREFERENCES for Each Corresponding ORGKEY. SO I wrote this Query;
update migadm.CORPMISCELLANEOUSINFO s set s.PREFERENCE_ID = (
select e.PREFERENCE_ID from crmuser.preferences e where s.ORGKEY = e.ORGKEY)
But I get:
ORA-01427: single-row subquery returns more than one row
What Should I do?
It means the columns you have selected are not unique enough to identify one row in your source table. Your first step would be to identify those columns.
To see the set of rows that have this problem, run this query.
select e.origkey,
count(*)
from crmuser.preferences e
group by e.origkey
having count(*) > 1
eg : for origkey of 2, let's say there are two rows in the preferences table.
orig_key PREFERENCE_ID
2 202
2 201
Oracle is not sure which of these should be used to update the preference_id column in CORPMISCELLANEOUSINFO
identify the row where the subquery returns more than one row (You could use REJECT ERROR clause to do it for instance) or use the condition 'where rownum = 1'.

Resources