SQL: Join tables on substrings - sql

I have a table A with the string-column a and a table B with the string-column b. a is a substring of b. Now I want to join the the two tables on a and b. Is this possible?
I want something like this:
Select * from A,B where A.a *"is substring of"* B.b
How can I write this in SQL (Transact-SQL)?

You can use like
select *
from A
inner join B
on B.b like '%'+A.a+'%'

declare #tmp1 table (id int, a varchar(max))
declare #tmp2 table (id int, b varchar(max))
insert into #tmp1 (id, a) values (1,'one')
insert into #tmp2 (id,b) values (1,'onetwo')
select * from #tmp1 one inner join #tmp2 two on charindex(one.a,two.b) > 0
You can also use charindex, 0 means its not found, greater than 0 is the start index
charindex

set an inner join on a substring(4 letters) of FIELD1 of table TABLE1 with FIELD1 of table TABLE2
select TABLE1.field1,TABLE2.field1 from TABLE1 inner join TABLE2 on substring(TABLE1.field1,2,5)=TABLE2.field1

You have the contains function:
http://msdn.microsoft.com/en-us/library/ms187787.aspx
select * from A,B where contains(B.b, A.a)

try this:
Select * from A,B where B.b LIKE '%'+A.a+'%'

Select * from A
Join B on B.b = substr(A.a, 1, 5)
The number 1 represents the first character of your string but you would pick the begin and the end of the characters you would like to match of course. Could be 5, 9 too for example.

Related

Hive join tables and keep only 1 column

I have below table join and noticed that Hive keeps two copies of the pk column - one from table b and one from table c. Is there a way to keep only 1 of those columns?
I can always replace select * with exact select column1, column2 etc but that wont be too efficient
with a as (
select
*
from table1 b left join table2 c
on b.pk = c.pk
)
select
*
from a;
;
#update 1
is it possible to alias many columns?
for example the below line works
select b.pk as duplicate_pk
but is there a way to do something like
select b.* as table2 to add text table2 before all the columns of the table b?
Not sure if you already tried this but you can choose what to select using either
b.* to select cols of only table1
c.* to select cols of only table2
Example:
with a as (
select
b.*
from table1 b left join table2 c
on b.pk = c.pk
)
select
*
from a;

find the code in table A which does not have in table B for particular gr_code

I have two table in my same DB
create table a(gr_code nvarchar, code int)
insert into a values('1',100),('0',200),('1',200),('0',100)
create table b(gr_code nvarchar, code int)
insert into b values('1',100),('0',200)
find the code in table A which does not have in table B for particular gr_code
expected result:
gr_code code
1 200
0 100
It's quite simple using the clause exists
select *
from a
where not exists (select *
from b
where b.gr_code = a.gr_code and
b.code = a.code)
This returns the result on your sample.
Use LEFT JOIN
select a.*
from a
left join b on a.gr_code = b.gr_code and a.code = b.code
where b.gr_code is null
You can use LEFT JOIN like this:
SELECT a.*
FROM a
LEFT JOIN b on a.gr_code = b.gr_code
WHERE b.gr_code IS NULL
You can use EXCEPT like so:
select *
from a
except
select *
from b

How i change this statement to dynamic SQL?

I trying to change this to be dynamic but I stuck at the set of data..
Example, the statement
SELECT * FROM A
WHERE id IN (1,2)
and also 1,2 come from
SELECT id FROM B
WHERE type='%xxx%'
Statement above can return many number
I try to declare #id but I have no idea
So, Have any idea?
Thank you for suggestion :)
SELECT * FROM A
WHERE id IN (
SELECT id FROM B
WHERE type='%xxx%')
This is called a subquery.
EDIT: When using a subquery is not an option and you want to use a variable, you can declare a temporary table and join table A with that table.
DECLARE #C table (id int)
INSERT #C (id)
SELECT id FROM B
WHERE type='%xxx%'
SELECT A.*
FROM A INNER JOIN #C c ON A.id = c.id
SELECT A.* FROM A
INNER JOIN B
WHERE B.type='%xxx%'
AND A.ID = B.ID
Perhaps you can just use inner join, it should return you the result set that you looking at

Inner join 2 tables but return all if 1 table empty

I have 2 tables say A and B, and I want to do a join on them.
Table A will always have records in it.
When table B has rows in it, I want the query to turn all the rows in which table A and table B matches. (i.e. behave like inner join)
However, if table B is empty, I'd like to return everything from table A.
Is this possible to do in 1 query?
Thanks.
Yes, for results like this, use LEFT JOIN.
Basically what INNER JOIN does is it only returns row where it has atleast one match on the other table. The LEFT JOIN, on the other hand, returns all records on the left hand side table whether it has not match on the other table.
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
I came across the same question and, as it was never answered, I post a solution given to this problem somewhere else in case it helps someone in the future.
See the source.
select *
from TableA as a
left join TableB as b
on b.A_Id = a.A_Id
where
b.A_Id is not null or
not exists (select top 1 A_Id from TableB)
Here is another one, but you need to add one "null" row to table B if it's empty
-- In case B is empty
Insert into TableB (col1,col2) values (null,null)
select *
from TableA as a inner join TableB as b
on
b.A_Id = a.A_Id
or b.A_Id is null
I would use an if-else block to solve it like below:
if (select count(*) from tableB) > 0
begin
Select * from TableA a Inner Join TableB b on a.ID = b.A_ID
end
else
begin
Select * from TableA
end
Try This
SELECT t1.* FROM table1 AS t1 INNER JOIN table2 AS t2 ON t1.something = t2.someotherthing UNION SELECT * FROM table1 WHERE something = somethingelse;
This is solution:
CREATE TABLE MyData(Id INT, Something VARCHAR(10), OwnerId INT);
CREATE TABLE OwnerFilter(OwnerId INT);
SELECT *
FROM
(SELECT NULL AS Gr) AS Dummy
LEFT JOIN OwnerFilter F ON (1 = 1)
JOIN MyData D ON (F.OwnerId IS NULL OR D.OwnerId = F.OwnerId);
Link to sqlfiddle: http://sqlfiddle.com/#!6/0f9d9/7
I did the following:
DECLARE #TableB TABLE (id INT)
-- INSERT INTO #TableB
-- VALUES (some ids to filter by)
SELECT TOP 10 *
FROM [TableA] A
LEFT JOIN #TableB B
ON A.ID = B.id
WHERE B.id IS NOT NULL
OR iif(exists(SELECT *
FROM TableB), 1, 0) = 0
Now:
If TableB is empty (leave the commented lines commented) you'll get the top 10.
If TableB has some ids in it, you'll only join by those.
I do not know how efficient this is. Comments are welcome.
Maybe use a CTE
;WITH ctetable(
Select * from TableA
)
IF(EXISTS(SELECT 1 FROM TableB))
BEGIN
Select * from ctetable
Inner join TableB
END
ELSE
BEGIN
Select * from ctetable
END
or dynamic SQL
DECLARE #Query NVARCHAR(max);
SET #QUERY = 'Select * FROM TableA';
IF(EXISTS(SELECT 1 FROM TableB))
BEGIN
SET #QUERY = CONCAT(#QUERY,' INNER JOIN TableB');
END
EXEC sp_executesql #Query

Sql Query help to get non matching records from two tables

I am trying to get non matching records from 2 tables
For ex
TableA
ID Account
1 Acc1
2 Acc2
3 Acc3
TableB
Opp Accountid
Opp1 1
Opp2 2
Opp3 4
I need to know which accountid is present in TableB but not in TableA. It would be wonderful if someone could provide this query.
Required record would be Opp3 of tableB
Thanks
Prady
SELECT B.Accountid
FROM TableB AS B
LEFT
JOIN TableA AS A
ON A.ID = B.Accountid
WHERE A.ID IS NULL;
LEFT JOIN means it takes all the rows from the first table - if there are no matches on the first join condition, the result table columns for table B will be null - that's why it works.
create table #one (id int,acc nvarchar(25))
insert into #one (id , acc) values(1,'one')
insert into #one (id , acc) values(2,'two')
insert into #one (id , acc) values(3,'three')
create table #two (acct nvarchar(25),ids int)
insert into #two (acct,ids) values('one',1)
insert into #two (acct,ids) values('two',3)
insert into #two (acct,ids) values('four',4)
select ids from #two EXCEPT select id from #one
drop table #one
drop table #two
test this one
SELECT B.Accountid
FROM TableB AS B
LEFT JOIN TableA AS A ON A.ID = B.Accountid
WHERE A.ID IS NULL
try this
(select * from t1
except
select * from t2)
union
(select * from t2
except
select * from t1)
thinking that you have the same number of columns in both tables
query mentioned above select ids from #two EXCEPT select id from #one
will give u non matching rows from only #two . it will neglect that of #one
This will generate same results.
select * from TableB where Accountid not in (select ID from TableA)