sql script help needed with joins - sql

How to merge 3 tables data with a common column.
create table #t1 (id varchar(3), name_1 varchar(10))
insert into #t1 values (101,'red')
insert into #t1 values (102,'green')
insert into #t1 values (103,'blue')
create table #t2 (id varchar(3), address_1 varchar(10), state_1 varchar(10))
insert into #t2 values (101,'lon','ab')
insert into #t2 values (101,'fin','pq')
insert into #t2 values (102,'san','cd')
insert into #t2 values (102,'new', 'mn')
create table #t3 (id varchar(3), examdt varchar(10), examtime varchar(10), centre_code varchar(10))
insert into #t3 values (101,'2017-01-01','08:05', 'cod')
insert into #t3 values (101,'2018-04-15','07:15','salm')
insert into #t3 values (101,'2015-08-08', '12:25','targ')
insert into #t3 values (102,'2019-03-11','09:45', 'hen')
insert into #t3 values (102,'2020-05-25','17:15','mint')
insert into #t3 values (103,'2015-05-08', '12:45','fish')
I tried:
select u.id, name_1, address_1, state_1, examdt, examtime, centre_code from
(
select id from #t1 union
select id from #t2 union
select id from #t3 ) as u left outer join #t1 on #t1.id = u.id
left outer join #t2 on #t2.id = u.id
left outer join #t3 on #t3.id = u.id
After running the above script, it is doing a cross join.
I want it should bring 3 rows with all non-common columns.

I think you want an inner join. I updated the ID values in your inserts as based on the description I think you meant to insert ID 101, 102, and 103 (not all of them as 101).
Updated table create statements:
create table #t1 (id varchar(3), name_1 varchar(10))
insert into #t1 values (101,'red')
insert into #t1 values (102,'green')
insert into #t1 values (103,'blue')
create table #t2 (id varchar(3), address_1 varchar(10), state_1 varchar(10))
insert into #t2 values (101,'lon','ab')
insert into #t2 values (102,'san','cd')
insert into #t2 values (103,'new', 'mn')
create table #t3 (id varchar(3), examdt varchar(10), examtime varchar(10), centre_code varchar(10))
insert into #t3 values (101,'2017-01-01','08:05', 'cod')
insert into #t3 values (102,'2018-05-15','07:15','salm')
insert into #t3 values (103,'2015-05-08', '12:25','targ')
Query to return data from all 3 tables:
select u1.id, u1.name_1, u2.address_1, u2.state_1, u3.examdt, u3.examtime, u3.centre_code
from #t1 u1
join #t2 u2 on (u2.id = u1.id)
join #t3 u3 on (u3.id = u1.id)
Output:
id |name_1|address_1|state_1|examdt |examtime|centre_code|
---+------+---------+-------+----------+--------+-----------+
101|red |lon |ab |2017-01-01|08:05 |cod |
102|green |san |cd |2018-05-15|07:15 |salm |
103|blue |new |mn |2015-05-08|12:25 |targ |

one unique key constraint will solve the issue across three tables.

Related

Get result based on Row_number criteria

I have tables three tables: #T, #T1, #Maintable, for which I'll attach the corresponding DDL.
Create table #T ( id int , reason varchar (50));
insert into #T Values (1,'Texas for live music');
insert into #T Values (1,'Texas for BBQ');
insert into #T Values (2,'Wisconsin for dairy products');
insert into #T Values (2,'Wisconsin for Rock');
insert into #T Values (2,'Wisconsin for Bird');
insert into #T Values (3,'North Carolina for Pepsi');
insert into #T Values (4,'Missouri for Forest');
insert into #T Values (5,'Oklohoma for cowboy');
insert into #T Values (5,'Oklohoma for Native Americans');
insert into #T Values (5,'Oklohoma for oil and gas');
Create table #T1 ( id int , reason varchar (50));
insert into #T1 Values (1,'Texas for live music,BBQ');
insert into #T1 Values (2,'Wisconsin for dairy products, rock,bird');
insert into #T1 Values (3,'North Carolina for Pepsi');
insert into #T1 Values (4,'Missouri for Forest');
insert into #T1 Values (5,'Oklohoma for Native Americans,oil and gas');
Create table #MainTable (id int, State varchar(20),Capital varchar(30),Governer varchar(30));
Insert into #Maintable values (1,'Texas','Austin','A');
Insert into #Maintable values (2,'Wisconsin','Madison','B');
Insert into #Maintable values (3,'North Carolina','Releigh','C');
Insert into #Maintable values (4,'Missouri','Jefferson City','D');
Insert into #Maintable values (5,'Oklohoma','Oklohoma city','E');
Expected Output
ID
Reason
State
Capital
Governer
1
Texas for live music,BBQ
Texas
Austin
A
2
Wisconsin for dairy products, rock,bird
Wisconsin
Madison
B
3
North Carolina for Pepsi
North Carolina
Releigh
C
4
Missouri for Forest
Missouri
Jefferson City
D
5
Oklohoma for Native Americans,oil and gas
Oklohoma
Oklohoma city
E
I have a couple of tables, based on the criteria I will be filtering records from table #T and joining with other tables to get more columns but with the help of cte, I am not able to filter. if first table #T has more than one Id then we will be using reason from another table #T1. If it has only one Id then we will be using Reason from Table #T and finally, we will join with #main table to get other records. I have added an image describing more. Help is much appreciated. All those temp tables we can test
And the scenario is:
If reason appears more than once in #T table use #T1 table
If reason appears only once in the #T table use #T only, this is the first table
Here's my coding attempt:
with cte as (
select *, ROW_NUMBER() over (partition by id order by id) rn
from #T
)
select mt.id, state, capital, Governer,
case when c.rn > 1
then #t1.reason
else c.reason
end as reason
from cte c
join #t1 on c.id = #t1.id
join #maintable mt on c.id = mt.id
I am getting more results, I was expecting only 5 records. I guess there is some issue in my row_number. Help is appreciated.
You should first extract the ranking value from the table "#T" for each ID. Then you can use the COALESCE function in combination with LEFT JOIN operations to solve your problem:
WITH #T_ranked AS (
SELECT *, ROW_NUMBER() OVER(PARTITION BY id ORDER BY reason) AS rn
FROM #T
)
SELECT m.id,
COALESCE(#T1.reason, #T_ranked.reason) AS Reason,
m.State,
m.Capital,
m.Governer
FROM #Maintable m
LEFT JOIN #T1 ON m.id = #T1.id
LEFT JOIN #T_ranked ON m.id = #T_ranked.id AND #T_ranked.rn = 1
The LEFT JOIN operations will make your ids in the "MainTable" be kept, while the COALESCE function will make the first non-null argument to be the value for the "Reason" new field, in the specific case it will check whether "#T1.Reason" is null, if it is then it will assign "#T2.Reason". Values from "#T.Reason" which have an existing correspondent in "#T1.Reason" will never be selected in this way.
Check the demo here.

SQL server : Replace the value using like operator

I need to replace the column value if exists to another column have a same text as like below example.
create table #t1
(
a varchar(100)
)
create table #t2
(
b varchar(100),
c varchar(100)
)
insert into #t1 values('she is a girl teacher and he is a boy doctor')
insert into #t2 values('girl','G')
insert into #t2 values('boy','B')
select *from #t1
select *from #t2
select a=replace (t1.a,t2.b,t2.c)
from #t1 t1 inner join #t2 t2 on t1.a like '%'+t2.b+'%'
while i'm selecting the query the result displays like
she is a G teacher and he is a boy doctor
she is a girl teacher and he is a B doctor
but i have need the output like
she is a G teacher and he is a B doctor
How need to change my query for the above output.
The only solution I can think if using recursive queries.
create table #t1
(
a varchar(100)
)
create table #t2
(
b varchar(100),
c varchar(100)
)
insert into #t1 values('she is a girl teacher and he is a boy doctor')
, ('she is a girl soldier and he is a boy doctor')
, ('she is a girl dentist and he is a boy farmer')
insert into #t2 values('girl','G')
insert into #t2 values('boy','B')
select *from #t1
select *from #t2
select a=replace(t1.a,t2.b,t2.c), *
from #t1 t1
inner join #t2 t2 on t1.a like '%'+t2.b+'%';
with cte as (
select a, 1 as ct from #t1
union all
select cast(replace(a,t2.b,t2.c) as varchar(100)) as a, ct+1 from cte
cross apply #t2 t2 where a like '%'+t2.b+'%'
)select distinct a from (select a, ct as ct from cte) as t1 where t1.ct = (select max(ct) from cte);
drop table #t1
drop table #t2
-- she is a G teacher and he is a B doctor
The most straightforward way is to just use a cursor to loop through all the replacements, applying them.
create table #t1
(
a varchar(100)
)
create table #t2
(
b varchar(100),
c varchar(100)
)
insert into #t1 values('she is a girl teacher and he is a boy doctor')
insert into #t2 values('girl','G')
insert into #t2 values('boy','B')
-- We create a couple of variables and a temporal table to hold the incremental replacements
declare #Pattern varchar(64)
declare #Value varchar(64)
select * into #TempReplacements from #1
-- Apply the replacements
declare Replacements cursor for select b, c from #t2
open Replacements
fetch next from Replacements into #Pattern, #Value
while ##fetch_status = 0
update #TempReplacements set a = replace(a, #Pattern, #Value)
fetch next from Replacements into #Pattern, #Value
end
close Replacements
deallocate Replacements
-- We return the results
select * from #TempRelacements
-- Drop temporary Table
drop table #TempReplacements
drop table #t1
drop table #t2

SQL syntax to get all possible combinations when joining 3 tables

I have tables T1, T2, T3 with values
CREATE TABLE #T1
(
[user1] char(20)
)
INSERT INTO #T1 VALUES ('A'), ('B'), ('C'), ('D')
CREATE TABLE #T2
(
[user2] char(20)
)
INSERT INTO #T2 VALUES ('D'), ('E'), ('F'), ('G')
CREATE TABLE #T3
(
[user3] char(20)
)
INSERT INTO #T2 VALUES ('D'), ('E'), ('C'), ('H')
I want the result to by display like
user1 user2 user3
-------------------------
A NULL NULL
B NULL NULL
C NULL C
D D D
NULL E E
NULL F NULL
NULL NULL H
I tried this:
select
user1,
user2,
user3
from
#T1
full join
#T2 on #T1.user1 = #T2.user2
full join
#T3 on #T2.user2 = #T3.user3
But obviously I missing something. Thanks for the help
You just needed to add an extra predicate to the join on #T3. So this:
full outer join #T3 on #T2.user2 = #T3.user3
becomes this:
full outer join #T3 on #T2.user2 = #T3.user3 OR #t3.user3 = #T1.user1
I am assuming your sample data had a typo since you meant to insert into #t3 in the last section. And you posted desired output is also missing NULL, G, NULL
Here's the full corrected code:
CREATE TABLE #T1
(
user1 char(20)
)
insert into #T1 VALUES ('A')
insert into #T1 VALUES ('B')
insert into #T1 VALUES ('C')
insert into #T1 VALUES ('D')
CREATE TABLE #T2
(
user2 char(20)
)
insert into #T2 VALUES ('D')
insert into #T2 VALUES ('E')
insert into #T2 VALUES ('F')
insert into #T2 VALUES ('G')
CREATE TABLE #T3
(
user3 char(20)
)
insert into #T3 VALUES ('D')
insert into #T3 VALUES ('E')
insert into #T3 VALUES ('C')
insert into #T3 VALUES ('H')
select
user1,
user2,
user3
from #T1
full outer join #T2 on #T1.user1 = #T2.user2
full outer join #T3 on #T2.user2 = #T3.user3 OR #t3.user3 = #T1.user1
drop table #T1
drop table #T2
drop table #T3

Join without foreign key for condition

I get two tables like this:
create table #table1 (data1 int)
create table #table2 (data2 int)
insert into #table1 (data1) values (1),(2),(3)
insert into #table2 (data2) values (4),(5),(6)
I want to make a query, that returns two columns like this:
data1 data2
1 4
2 5
3 6
I found one solution for this:
select t1.data1, t2.data2 from
(select row_number() over (order by data1) as [Index], data1 from #table1) as t1 inner join
(select row_number() over (order by data2) as [Index], data2 from #table2) as t2 on (t1.[Index] = t2.[Index])
Do you know other ways to join tables (any joins except cross) without keys?
EDIT: I look for solution without cursor and temporary tables.
create table table1 (data1 int)
create table table2 (data2 int)
insert into table1 (data1) values (1),(2),(3)
insert into table2 (data2) values (4),(5),(6)
create table #table1
(id int identity(1,1),
data1 int)
create table #table2
(id int identity(1,1),
data2 int)
insert into #table1 (data1) select data1 from table1
insert into #table2 (data2) select data2 from table2
create table table3
(data1 int,
data2 int)
insert into table3 (data1, data2)
select #table1.data1, #table2.data2
from #table1
inner join #table2 on #table1.id = #table2.id
what will be output in this case if i insert below values
insert into #table1 (data1) values (1),(2),(3)
insert into #table2 (data2) values (2),(3),(4)
may you need
select t1.data1, t2.data2 from t1,t2

Select query : from clause is having multple tables, but i want where clause to have condition on only two tables

For eg:
SELECT aa.name, aa.id
FROM ba_acct_memo aa, acct_mast bb
WHERE (aa.cod_acct_no=bb.cod_acct_no AND aa.flg_mnt_status='U'
and bb.flg_mnt_status='A')
gives 1 row(for eg)
but
SELECT aa.name, aa.id
FROM ba_acct_memo aa, acct_mast bb, college cc
WHERE (aa.cod_acct_no=bb.cod_acct_no AND aa.flg_mnt_status='U'
and bb.flg_mnt_status='A')
gives same result as in first query but giving it, as many number of rows which are there in college table.
But it should work just as like first query.
Can someone explain the weird behaviour of my query?
Following Steps will help you to understand (Inner) Join.
--Create Table 1 :
Create Table #Table1
(
Roll_No INT ,
Student_Name Varchar(50)
)
Go
--Create Table 2 :
Create Table #Table2
(
Roll_No INT,
Student_Address Varchar(200)
)
Go
--Create Table 3 :
Create Table #Table3
(
Roll_No INT,
Student_Contact_No Varchar(10)
)
Go
-- Insert Values into #Table1:
Insert into #Table1 Values ('1','John')
Insert into #Table1 Values ('2','Alex')
Insert into #Table1 Values ('3','Mike')
Insert into #Table1 Values ('4','Steve')
Insert into #Table1 Values ('5','Jack')
Insert into #Table1 Values ('6','Vicky')
Insert into #Table1 Values ('7','Sid')
Insert into #Table1 Values ('8','Tom')
-- Insert Values into #Table2:
Insert into #Table2 Values ('1','1st Street')
Insert into #Table2 Values ('2','2rd Street')
Insert into #Table2 Values ('3','3rd Street')
Insert into #Table2 Values ('4','4th Street')
Insert into #Table2 Values ('5','5th Street')
Insert into #Table2 Values ('6','6th Street')
Insert into #Table2 Values ('7','7th Street')
Insert into #Table2 Values ('8','8th Street')
-- Insert Values into #Table3:
Insert into #Table3 Values ('1','123-123')
Insert into #Table3 Values ('2','123-111')
Insert into #Table3 Values ('3','123-122')
Insert into #Table3 Values ('4','123-125')
Insert into #Table3 Values ('5','123-126')
Insert into #Table3 Values ('6','123-116')
Insert into #Table3 Values ('7','123-145')
Insert into #Table3 Values ('8','123-132')
--View Data :
Select * from #Table1
Select * from #Table2
Select * from #Table3
-- First Query : (With Out Third Table) :
Select A.Roll_No,A.Student_Name,B.Student_Address from #Table1 A, #Table2 B
Where a.Roll_No = B.Roll_No
and a.Roll_No = 1
--It will Retrun One Record. If you add third table in this query with out join with any other tables ( Table 1 and Table 2 )
-- Secord Query :
Select A.Roll_No,A.Student_Name,B.Student_Address from #Table1 A, #Table2 B , #Table3 C
Where a.Roll_No = B.Roll_No
and a.Roll_No = 1
--It will return 8 Same Records. (Because Table 3 having 8 Records)
--You can understand when execute why it is return 8 records.
-- Third Query :
Select * from #Table1 A, #Table2 B , #Table3 C
Where a.Roll_No = B.Roll_No
and a.Roll_No = 1
--Delete some records from #Table 3 :
Delete #Table3 Where Roll_No > 5
--Execute again Third Query :
-- Third Query :
Select * from #Table1 A, #Table2 B , #Table3 C
Where a.Roll_No = B.Roll_No
and a.Roll_No = 1
--Clean Up:
Drop table #Table1
Drop table #Table2
Drop table #Table3