SQL syntax to get all possible combinations when joining 3 tables - sql

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

Related

set value using a conditional of a subquery

Sorry if I am not explaining my issue the best, but basically I have two tables.
Table A has a reference column to table B. On table B there is column X where for each referenced row, there is an unreferenced row with that same value of column X (table B has double the rows of table A). I want to update the reference on table A to be the row of table B that is not currently referenced of the two rows that have the same value on column X.
In pseudo code...
update tableA
set refCol = (select tableB.refCol
from tableB
where colX = (select colX
from tableB
where tableB.refCol = tableA.refCol)
and tableB.refCol != tableA.refCol)
The innermost query returns two rows, the outer query returns one row
sample tables:
Table A
refCol
1
3
Table B
refCol
colX
1
hello
2
hello
3
hi
4
hi
expected output:
Table A
refCol
2
4
Any help would be much appreciated.
Refer it below working example
create table #tableA(
id int)
create table #tableB(
id int,
name varchar(10)
)
insert into #tableA values(1)
insert into #tableA values(3)
insert into #tableA values(5)
insert into #tableA values(6)
insert into #tableA values(7)
insert into #tableA values(8)
insert into #tableB values (1,'A')
insert into #tableB values (2,'A')
insert into #tableB values (3,'C')
insert into #tableB values (4,'C')
select * from #tableA
select * from #tableB
update aa set aa.id=ab.id from #tableA aa inner join (
select b.id,b.name,a.id as ta from (
select B.* from #tableB b left join #tableA a on a.id=b.id where a.id is null)b
inner join (
select b.* from #tableA a inner join #tableB b on a.id=b.id)a on a.name=b.name)ab on aa.id=ab.ta

sql script help needed with joins

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.

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

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