sql query for like to Order exact match at top in list - sql

sql query for like to show exact match first in list:
dataset: "abcd", "a","b","bc","bcd"
select * from table where data like "%bc%";
it should show in order bc, abcd, bcd.

As you said - sort by match.
SQL> with test (col) as
2 (select 'abcd' from dual union all
3 select 'a' from dual union all
4 select 'b' from dual union all
5 select 'bc' from dual union all
6 select 'bcd' from dual
7 )
8 select col
9 from test
10 where col like '%' || '&&par_search_string' ||'%'
11 order by utl_match.jaro_winkler_similarity(col, '&&par_search_string') desc;
Enter value for par_search_string: bc
COL
----
bc
bcd
abcd
SQL> undefine par_search_string
SQL> /
Enter value for par_search_string: cd
COL
----
bcd
abcd
SQL>

One of many methods:
with
t as (
select 'abcd' c from dual union all
select 'a' from dual union all
select 'b' from dual union all
select 'bc' from dual union all
select 'bcd' from dual
)
select *
from t
where c like '%bc%'
order by length(c)
Demo.

I think you can use a query like this one that can return your expected result.
select * from table where data='bc'
union all
select * from table where data like '%bc%' and data<>'bc'

One method is:
select *
from t
where data like '%bc%'
order by (case when data = 'bc' then 1 else 2 end);
Or if you don't want to type so much:
order by nullif(data, 'bc') desc
The descending sort puts NULL values first.

Related

using regular expression that not include string '05613'. have NAW_05613_11_PL04_02 in table. need condition rows which have 05613 not be displayed

I want to fetch data from database using regular expression which should not include string '05613'.
I have values like NAW_05613_11_PL04_02 in my table. I want to give condition that all rows which have 05613 in it should not be displayed.
I have tried using REGEXP_LIKE(d.variable_value_string, '^N(*)[^{05613}](*)')
SELECT * from tablename where REGEXP_LIKE(columnname, '^N(*)[^{05613}](*)')
Expected result should be- row with value having 05613 should not be retrieved.
A simple LIKE could be enough:
... columnName not like '%05613%'
For example:
SQL> with test(c) as (
2 select '05613XX' from dual union all
3 select 'XX05613' from dual union all
4 select 'X05613X' from dual union all
5 select 'XXX' from dual
6 )
7 select *
8 from test
9 where c not like '%05613%';
C
-------
XXX
SQL>
If you need, for some reason, regexp_like, this is a way:
SQL> with test(c) as (
2 select '05613XX' from dual union all
3 select 'XX05613' from dual union all
4 select 'XX05613' from dual union all
5 select 'X05613X' from dual union all
6 select 'XXX' from dual
7 )
8 select *
9 from test
10 where not regexp_like(c, '05613');
C
-------
XXX
If this is your assignment and usage of regexp_like is mandated then use following regexp_like:
SELECT * from tablename D
where Not REGEXP_LIKE(d.variable_value_string, '05613')
Cheers!!

Select multiple rows and one value from dual

It's hard to explain but i would like to make query that display multiple rows in first column and one, same value in second column in Oracle
Something like this:
Select ('123', '456') First, 'abc' Second from dual;
How can i do that?
Probably shortest syntax is:
select column_value first, 'abc' second
from table(sys.odcivarchar2list('123', '456', '789', 'A1', 'B70', 'C44'))
Result:
FIRST SECOND
------ ------
123 abc
456 abc
789 abc
A1 abc
B70 abc
C44 abc
use union all
Select '123' First, 'abc' Second from dual
union all
select '456','abc' from dual
use union all
select '123', 'abc' from dual
union all
select '456','abc' from dual
another similar way
select * from (select '123' as col1 from dual
union all
select '456' from dual) a, (select 'abc' as col2 from dual) b
COL1 COL2
123 abc
456 abc
demo
BAM! Change the 20 to however many rows you want.
select level as first, 'abc' as second
from dual
connect by level <= 20;

Regular expression matching with Oracle

I am working on SQL Developer. I want only those records which have non-numeric data. The query I used is:
select * from TBL_NAME where regexp_like (mapping_name,'%[!0-9]%');
Strangely this is not working.
How about this? As you said, return values that are NOT numbers.
SQL> with test (col) as
2 (select 'abc123' from dual union
3 select '12345' from dual union
4 select 'abc' from dual union
5 select '($ff3' from dual union
6 select '12.345' from dual
7 )
8 select col
9 from test
10 where not regexp_like (col, '^\d+|(\.\d+)$');
COL
------
($ff3
abc
abc123
SQL>
If there are no decimal values, regular expression is even simpler: '^\d+$'
[EDIT, after sample data have been provided]
Piece of cake:
SQL> with test (col) as
2 (select 'ABC' from dual union
3 select 'BCE1' from dual union
4 select '2GHY' from dual union
5 select 'WE56S' from dual union
6 select 'TUY' from dual
7 )
8 select col
9 from test
10 where not regexp_like (col, '\d');
COL
-----
ABC
TUY
SQL>

Oracle Between return is not expected

I have a varchar colunm. with content
ColumnX
________
ABC
DEF
1
2
3
4
40
50
I need to get number between 1 and 4. SO i have this SQL
SELECT columnX
FROM table
WHERE regexp_substr(columnX, '[[:digit:]]') BETWEEN 1 and 4;
But my result i get is 1,2,3,4 and 40.
What shall I do to get it right?
You have to use a quantifier to match more than 1 character. In this case, I used the + quantifier, which matches one or more occurrences of the characters (digits, in this case).
Try this:
WITH
test_data AS
(SELECT 'ABC' AS columnX FROM dual
UNION ALL SELECT '1' FROM dual
UNION ALL SELECT '2' FROM dual
UNION ALL SELECT '3' FROM dual
UNION ALL SELECT '4' FROM dual
UNION ALL SELECT '40' FROM dual
UNION ALL SELECT '50' FROM dual
)
SELECT columnX
FROM test_data
WHERE regexp_substr(columnX, '[[:digit:]]+') BETWEEN 1 AND 4;
Output:
COLUMNX
-------
1
2
3
4

How to do select count(*) group by and select * at same time?

For example, I have table:
ID | Value
1 hi
1 yo
2 foo
2 bar
2 hehe
3 ha
6 gaga
I want my query to get ID, Value; meanwhile the returned set should be in the order of frequency count of each ID.
I tried the query below but don't know how to get the ID and Value column at the same time:
SELECT COUNT(*) FROM TABLE group by ID order by COUNT(*) desc;
The count number doesn't matter to me, I just need the data to be in such order.
Desire Result:
ID | Value
2 foo
2 bar
2 hehe
1 hi
1 yo
3 ha
6 gaga
As you can see because ID:2 appears most times(3 times), it's first on the list,
then ID:1(2 times) etc.
you can try this -
select id, value, count(*) over (partition by id) freq_count
from
(
select 2 as ID, 'foo' as value
from dual
union all
select 2, 'bar'
from dual
union all
select 2, 'hehe'
from dual
union all
select 1 , 'hi'
from dual
union all
select 1 , 'yo'
from dual
union all
select 3 , 'ha'
from dual
union all
select 6 , 'gaga'
from dual
)
order by 3 desc;
select t.id, t.value
from TABLE t
inner join
(
SELECT id, count(*) as cnt
FROM TABLE
group by ID
)
x on x.id = t.id
order by x.cnt desc
How about something like
SELECT t.ID,
t.Value,
c.Cnt
FROM TABLE t INNER JOIN
(
SELECT ID,
COUNT(*) Cnt
FROM TABLE
GROUP BY ID
) c ON t.ID = c.ID
ORDER BY c.Cnt DESC
SQL Fiddle DEMO
I see the question is already answered, but since the most obvious and most simple solution is missing, I'm posting it anyway. It doesn't use self joins nor subqueries:
SQL> create table t (id,value)
2 as
3 select 1, 'hi' from dual union all
4 select 1, 'yo' from dual union all
5 select 2, 'foo' from dual union all
6 select 2, 'bar' from dual union all
7 select 2, 'hehe' from dual union all
8 select 3, 'ha' from dual union all
9 select 6, 'gaga' from dual
10 /
Table created.
SQL> select id
2 , value
3 from t
4 order by count(*) over (partition by id) desc
5 /
ID VALU
---------- ----
2 bar
2 hehe
2 foo
1 yo
1 hi
6 gaga
3 ha
7 rows selected.