Exclude Redundant Wildcards (SQL) - sql

This is not a difficult problem to solve, but it doesn't seem to have been asked on the site so I thought I should post it
Sample Data:
wildcard
%abc%
abc
something abc%
ijk
this is mno
%mno%
Expected Output:
wildcard
%abc%
ijk
%mno%
Problem Statement:
List all wildcards except those that are redundant. For e.g. whatever matches with this is mno would match with %mno%, making the former redundant.

I found it easier to solve using not exists
with cte(wildcard) as
(select '%abc%' union all
select 'abc' union all
select 'something abc%' union all
select 'ijk' union all
select 'this is mno' union all
select '%mno%')
select *
from cte a
where not exists(select *
from cte b
where a.wildcard <> b.wildcard and
a.wildcard like b.wildcard)

Related

Binary Case when in Union Query

I am facing some problems and I got stuck in building this query.
I would like to stack 2 columns from the same table into a long single one (I use UNION statement), and then, I would like to produce a new variable to tell me if the number (stack of column1 and column2, organism_id) comes from column 1 or comes from column 2. For now, I have been trying this approach but I have a problem which I do not understand in the following query:
SELECT u.organism_id, case when u.organism_id IN cpl.column1 then 1
else 0
end as is_column1
FROM
(select column1 as organism_id
from table1
UNION
select column2
from table1) as u,
table1 as cpl;
Does someone have a clue on how to solve this problem?
Thanks in advance!
In general, and if I understand you correctly, you can throw a source column on the tables before unioning them. I'd also suggest UNION ALL to avoid accidental removal of duplicates:
SELECT
*
FROM
(
SELECT
'Column1' AS Source,
Column1
FROM
Table1
UNION ALL
SELECT
'Column2' AS Source,
Column2
FROM
Table1
) u

sql if statement in function

I have a fuction in visual basic and I'm sending a and b variables into the fuction. It does a lot of select statements as seen below:
SQL CODE
Select xxx where a=#a
union
Select yyy where u=#a
I want to add one more union with if statement.
I want to run one part if #b=1 and other part if #b=2
union
if #b=1
select zzz
if #b=2
select ttt
I want to learn how to use union with if statement and correct syntax of it.
union
if #b=1
begin
select zzz
end
else if( #b=2)
select ttt
end
is it correct?
Thanks.
I think you can put your checks in the WHERE clause. If they fail now rows are selected and therefore no rows are added to the overall result.
...
UNION
SELECT ...
WHERE #b = 1
UNION
SELECT ...
WHERE #b = 2;

Using switch to select columns and filter

Can we use switch case to filter the columns of a table in this way?
select distinct stud.name, stud.num,
case WHEN stud.sub like '%data%' THEN stud.sub
WHEN stud.sub like '%informatics%' THEN stud.sub
WHEN stud.sub like '%genomics%' THEN stud.sub
ELSE '---'
END
from table_A
The expected result is
Name ID Sub
victor 2098 -----
Lui 6754 Bioinformatics
Willis 7653 Advanceddatascience
Thanks!
Yes, your query should work. If you want to try something different, this should work in Oracle. Easy to change it to any other RDBMS.
Also easy to add any other subject.
With aux as ( select '%data%' as auxText from dual union all
select '%informatics%' as auxText from dual union all
select '%genomics%' as auxText from dual )
select distinct stud.name, stud.num,
nvl(stud.sub,'---') as sub
from table_A left join aux on table_A.sub like aux.auxText;

SQL: Select strings which have equal words

Suppose I have a table of strings, like this:
VAL
-----------------
Content of values
Values identity
Triple combo
my combo
sub-zero combo
I want to find strings which have equal words. The result set should be like
VAL MATCHING_VAL
------------------ ------------------
Content of values Values identity
Triple combo My combo
Triple combo sub-zero combo
or at least something like this.
Can you help?
One method is to use a hack for regular expressions:
select t1.val, t2.val
from t t1 join
t t2
on regexp_like(t1.val, replace(t2.val, ' ', '|');
You might want the case to be identical as well:
on regexp_like(lower(t1.val), replace(lower(t2.val), ' ', '|');
You could use a combination of SUBSTRING and LIKE.
use charIndex(" ") to split the words up in the substring if thats what you want to do.
Using some of the [oracle internal similiarity] found in UTL_Match (https://docs.oracle.com/database/121/ARPLS/u_match.htm#ARPLS71219) matching...
This logic is more for matching names or descriptions that are 'Similar' and where phonetic spellings or typo's may cause the records not to match.
By adjusting the .5 below you can see how the %'s get you closer and closer to perfect matches.
with cte as (
select 'Content of values' val from dual union all
select 'Values identity' val from dual union all
select 'triple combo' from dual union all
select 'my combo'from dual union all
select 'sub-zero combo'from dual)
select a.*, b.*, utl_match.edit_distance_similarity(a.val, b.val) c, UTL_MATCH.JARO_WINKLER(a.val,b.val) JW
from cte a
cross join cte b
where UTL_MATCH.JARO_WINKLER(a.val,b.val) > .5
order by utl_match.edit_distance_similarity(a.val, b.val) desc
and screenshot of query/output.
Or we could use an inner join and > if we only want one way compairisons...
select a.*, b.*, utl_match.edit_distance_similarity(a.val, b.val) c, UTL_MATCH.JARO_WINKLER(a.val,b.val) JW
from cte a
inner join cte b
on A.Val > B.Val
where utl_match.jaro_winkler(a.val,b.val) > .5
order by utl_match.edit_distance_similarity(a.val, b.val) desc
this returns the 3 desired records.
But this does not explicitly check each any word matches. which was your base requirement. I just wanted you to be aware of alternatives.

Help with T-sql special sorting rules

I have a field likeļ¼š
SELECT * FROM
(
SELECT 'A9t' AS sortField UNION ALL
SELECT 'A10t' UNION ALL
SELECT 'A11t' UNION ALL
SELECT 'AB9F' UNION ALL
SELECT 'AB10t' UNION ALL
SELECT 'AB11t'
) t ORDER BY sortField
and the result is:
sortField
---------
A10t
A11t
A9t
AB10t
AB11t
AB9F
Actually I need is to combine the string and number sorting rules:
sortField
---------
A9t
A10t
A11t
AB9F
AB10t
AB11t
SELECT *
FROM (
SELECT 'A9t' AS sortField UNION ALL
SELECT 'A10t' UNION ALL
SELECT 'A11t' UNION ALL
SELECT 'AB9F' UNION ALL
SELECT 'AB10t' UNION ALL
SELECT 'AB11t'
)
t
ORDER BY LEFT(sortField,PATINDEX('%[0-9]%',sortField)-1) ,
CAST(substring(sortField,PATINDEX('%[0-9]%',sortField),1 + PATINDEX('%[0-9][A-Z]%',sortField) -PATINDEX('%[0-9]%',sortField) ) AS INT),
substring(sortField,PATINDEX('%[0-9][A-Z]%',sortField) + 1,LEN(sortField))
If the first character is always a letter, try:
SELECT * FROM
(
SELECT 'A9t' AS sortField UNION ALL
SELECT 'A10t' UNION ALL
SELECT 'A11t'
) t ORDER BY substring(sortField,2,len(sortField)-1) desc
I would say that you have combined the alpha and numeric sort. But what I think you're asking is that you want to sort letters in ascending order and numbers in descending order, and that might be hard to do in a nice looking way. The previous answers will not working for your problem, the problem is that Martin Smith's solution doesn't take strings with two letters as prefix and Parkyprg doesn't sort numbers before letters as you ask for.
What you need to do is to use a custom order, see example here: http://www.emadibrahim.com/2007/05/25/custom-sort-order-in-a-sql-statement/, but that is a tedious way to do it.
EDIT: Martins Smith's solution is updated and works just fine!