I have a situation where I need to combine two different tables with different columns.
DDL:
create table tableA ([timestamp] datetime, [source] char(1), [description] varchar(20));
insert into tableA values
('2018-10-12', 'a', 'first day'),
('2018-10-13', 'b', 'alarms'),
('2018-10-14', 'c', 'processing');
create table tableB ([timestamp] datetime, entity varchar(20));
insert into tableB values
('2018-10-12', 'new env'),
('2018-10-13', 'resource'),
('2018-10-18', 'integrated');
I have different columns in two different tables. And I need to combine it as shown in screenshot using SQL.
Use union all
select a.timestamp, a.source,a.description,b.entity
from tableA a left join tableB b on a.timestamp=b.timestamp
where b.timestamp is not null
union all
select b.timestamp, a.source,a.description,b.entity
from tableA a right join tableB b on a.timestamp=b.timestamp
where a.timestamp is null
You can use INNER JOIN for this
SELECT a.TimeStamp, a.Source, a.Description, b.Entity
FROM TableA a
LEFT JOIN Tableb b ON a.TimeStamp=b.TimeStamp;
UNION
SELECT a.TimeStamp, a.Source, a.Description, b.Entity
FROM TableA a
RIGHT JOIN Tableb b ON a.TimeStamp=b.TimeStamp;
You need to use full join. Try this query:
select coalesce (a.timestamp, b.timestamp), source, description, entity
from tableA a
full join tableB b on a.timestamp = b.timestamp
Demo
Use Below code
SELECT isnull(t1.TimeStamp, t2.TimeStamp) TimeStamp, t1.source,t1.description, t2.entity from table1 t1 FULL OUTER JOIN table2 t2 on t1.id=t2.id
Related
INSERT INTO Table1(group, account)
OUTPUT inserted.Id, B.title, B.amount
INTO Table2(id2, title, amount)
SELECT A.*,
B.title,
B.amount,
B.id2
FROM Table1 AS A
LEFT OUTER JOIN
(SELECT title,
amount,
id2
FROM Table2) AS B
ON A.id = B.id2
i'm stuck with this..i have two join tables and what i want is to copy the same set of data from table1 to itself and copy the new id of the newly copied data from table1 to table2 column id2 by using OUTPUT clause.
but now with the query above i cant get through the column that i needed..how can i insert column B.title & B.amount to table2 ?
If table 1 and table 2 have a 1:1 relationship, and no foreign key exists between the two then you could do this in a single statement:
MERGE Table1 AS a
USING
( SELECT A.[group], A.account, B.title, B.amount, B.id2
FROM Table1 AS A
LEFT OUTER JOIN Table2 AS B
ON A.id = B.id2
) AS b
ON 1 = 0
WHEN NOT MATCHED THEN
INSERT ([group], account)
VALUES (b.[group], b.account)
OUTPUT inserted.Id, B.title, B.amount
INTO Table2(id2, title, amount);
Example on SQL Fiddle
Realistically though, if your tables are related they should have a foreign key, and in most cases they won't be 1:1, rather 1:n.
In which case you would still need to use MERGE to caputre both the new ID and the old ID, but you would then need to capture this mapping in a temporary table before performing a second insert to Table2:
DECLARE #Map TABLE (OldID INT NOT NULL, NewID INT NOT NULL);
MERGE Table1 AS a
USING
( SELECT A.ID, A.[group], A.account
FROM Table1 AS A
) AS b
ON 1 = 0
WHEN NOT MATCHED THEN
INSERT ([group], account)
VALUES (b.[group], b.account)
OUTPUT inserted.Id, b.ID
INTO #Map(NewID, OldID);
INSERT Table2 (id2, title, amount)
SELECT m.NewID, b.title, b.amount
FROM #Map AS m
INNER JOIN Table2 AS b
ON b.ID2 = m.OldID;
Example on SQL Fiddle
I have the following tables
Table A
ID "Other Columns"
1
2
3
Table B
ID "Other Columns"
3
4
5
What is the efficient way to return the below result?
Result
ID "Other Columns"
1
2
4
5
A full outer join should work, and only go through each table once. They can be tricky, so test carefully!
SELECT
isnull(A.ID, B.ID) ID
,"Other columns" -- Handle nulls properly!
from TableA A
full outer joing TableB B
on B.ID = A.ID
where not (A.ID is not null
and B.ID is not null)
You want to use left and right join and union them
Select TableA.ID as 'ID','Other Colums'
FROM TableA Left join TableB
ON TableA.ID=TableB.ID
WHERE TableB.ID IS NULL
UNION
Select TableB.ID as 'ID','Other Colums'
FROM TableA Right join TableB
ON TableA.ID=TableB.ID
WHERE TableA.ID IS NULL
You can try like this
SELECT
COALESCE(a.id, b.id),
OtherColumns
FROM #tablea a
FULL JOIN #tableb b
ON a.id = b.id
WHERE a.id IS NULL
OR b.id IS NULL
You can do this with a UNION ALL using a LEFT JOIN to determine if the ID is not in the other table. Keep in mind that the column count and datatypes between the two tables must match up:
Select A.Id, A.OtherColumns
From TableA A
Left Join TableB B On A.Id = B.Id
Where B.Id Is Null
Union All
Select B.Id, B.OtherColumns
From TableB B
Left Join TableA A On A.Id = B.Id
Where A.Id Is Null
Not quite sure what you need with the "Other columns", but you could use EXCEPT:
Select ID from TableA
EXCEPT
Select ID from TableB
If you need Other columns from TableA you could use:
Select ID, OtherColumn1, OtherColumn2 from TableA
where ID not in (select ID from TableB)
(as long as ID cannot be null in TableB)
I broke down each part to be clearer!
select *
into #temp
from
TabA Full outer join TabB
on TabA.ColNameA = TabB.ColNameB
select *
into #temp2
from #temp
where (ColNameA is Null Or ColNameB is null)
select ColNameA from #temp2
where ColNameA Is not null
union
select ColNameB from #temp2
where ColNameB Is not null
I have two tables in join. Here i have to get mapped records when the Second table has set of records. But when the Second table has no record i need all records from first table.
Create Table #temp1
(Id1 int)
Create Table #temp2
(Id2 int)
Insert into #temp1 Values(1),(2),(3),(4)
Insert into #temp2 Values(1),(2)
Select * from #temp1 A
Inner Join #temp2 B On A.Id1=B.Id2
It gives correct output when i have records in second table.
But when i have no records in second table i need to get all records from first table.
Delete #temp2
Select * from #temp1 A
Inner Join #temp2 B On A.Id1=B.Id2
this query return no records i tried with Left Outer Join it give all records but i am not getting records like first scenario.
Drop Table #temp1
Drop Table #temp2
I need output like this.
Thanks in Advance.
if question is not clear ,please ask me.
If you only want columns from the first table:
select a.*
from #temp1 a
where exists (select 1 from #temp2 b where b.id2 = a.id1) or
not exists (select 1 from #temp2 b);
If you wanted the extra columns from the second table, you could use union all:
Select a.*, b.*
from #temp1 a Inner Join
#temp2 b
On a.Id1 = b.Id2
union all
select a.*, b.*
from #temp1 a left join
#temp2 b
on a.id1 = b.id2
where not exists (select 1 from #temp2);
Actually you can use an OUTER JOIN:
SELECT Id1 FROM #temp1 t1
LEFT OUTER JOIN #temp2 t2
ON t1.Id1 = t2.Id2
Left join seems to work fine:
Select a.id1
from #temp1 A
left Join #temp2 B On A.Id1=B.Id2
Demo here
I have a stored procedure that joins in numerous tables and selects fields from them. One of the tables being a temporary table.
SELECT
a.Field1,
a.Field2,
b.Field3,
b.Field4,
c.Field5
FROM table1 a
LEFT JOIN #table2 b ON a.Field1 = b.Field1
INNER JOIN table3 c ON a.Field1 = c.Field1
The above takes 10+ minutes, however if I comment out the two b fields from the select while leaving the join in place it runs in just seconds.
I have pulled this out of procedure to simplify and same behavior. Also the execution plans are almost identical.
Any help is appreciated.
How many rows are in the temp table, and is "Field2" in the temp table a primary key?
If you're not selecting any rows from the right table of a left join, and the join is to the primary key (or possibly a unique key), and you reference no columns from the right table, SQL Server can avoid having to access the temp table at all (since the presence or absence of a joining row has no impact on the final result):
Example. Table setup:
create table T1 (
ID int not null primary key,
Col1 varchar(10) not null
)
go
insert into T1 (ID,Col1)
select 1,'a' union all
select 2,'b' union all
select 3,'c'
go
create table #t2 (
ID int not null primary key,
Col2 varchar(10) not null
)
go
insert into #t2 (ID,Col2)
select 1,'d' union all
select 2,'e' union all
select 4,'f'
go
create table #t3 (
ID int not null,
Col3 varchar(10) not null
)
go
insert into #t3 (ID,Col3)
select 1,'d' union all
select 2,'e' union all
select 1,'f'
And the queries:
select T1.ID,T1.Col1 from T1 left join #t2 t2 on T1.ID = t2.ID
select T1.ID,T1.Col1,t2.Col2 from T1 left join #t2 t2 on T1.ID = t2.ID
select T1.ID,T1.Col1 from T1 left join #t3 t3 on T1.ID = t3.ID
select T1.ID,T1.Col1,t3.Col2 from T1 left join #t2 t3 on T1.ID = t3.ID
In all but the first query, the join happens as expected. But because the presence or absence of rows in #t2 can't affect the final result for the first query, it avoids performing the join entirely.
But if it's not something like that (and I'd expect it to be an obvious difference in the query plans)< I#m a bit stumped.
Have you tried inverting the joins? (although you are missing a join condition for table c in the sample query)
SELECT
a.Field1,
a.Field2,
b.Field3,
b.Field4,
c.Field5
FROM table1 a
INNER JOIN table3 c
LEFT JOIN #table2 b ON a.Field1 = b.Field1
I would try adding an index with included columns to #table2 and see if it helps:
CREATE NONCLUSTERED INDEX IX_table2
ON #table2 (Field1)
INCLUDE (Field3, Field4);
How about running the query in two parts. Make the first part as restrictive as possible and then only outer join on the filtered set.
SELECT a.Field1,
a.Field2,
b.Field3,
c.Field5
INTO #t
FROM table1 a
INNER JOIN table3 c ON a.Field1 = c.Field1
SELECT t.Field1,
t.field2,
b.field3,
b.field4,
t.field5
FROM #t t
LEFT OUTER JOIN #table2 b ON t.Field1 = b.Field1
select * into #temp from table1
select * into #temp1 from table2
select * into #temp2 from table3
SELECT
a.Field1,
a.Field2,
b.Field3,
b.Field4,
c.Field5
FROM #temp a
LEFT JOIN #temp1 b ON a.Field1 = b.Field1
INNER JOIN #temp2 c ON a.Field1 = c.Field1
if(Object_Id('TempDB..#temp') Is Not Null)
Begin
Drop table #temp
End
if(Object_Id('TempDB..#temp1') Is Not Null)
Begin
Drop table #temp1
End
if(Object_Id('TempDB..#temp2') Is Not Null)
Begin
Drop table #temp2
End
I'm facing with a join problem in sql server 2005 database.
I've the following tables structure:
TableA --LEFT JOIN--> TableB --INNER JOIN-->TableC
So if I write a query like this:
SELECT TableA.* FROM TableA
LEFT OUTER JOIN TableB ON TableA.keyOfB = TableB.key
INNER JOIN TableC ON TableB.keyOfC = TableC.key
where TableA.key = aValue
it read 0 record if there's not any TableB record associated with TableA record.
But TableB is in outer join, so this is not what I expected. In other words, the INNER JOIN shouldn't have been considerer because there's not any TableB record!
What I'm missing?
I think it has to do with the order of JOIN operations.
The result of (A LEFT OUTER JOIN B) INNER JOIN C, you want A LEFT OUTER (B INNER JOIN C).
Try dropping some () in there.
Or try reordering your JOINS to ... B INNER C RIGHT OUTER A to get (B INNER C) RIGHT OUTER A.
EDIT:
Example of what I was thinking:
SELECT TableA.* FROM TableA
LEFT OUTER JOIN (TableB INNER JOIN TableC ON TableB.keyOfC = TableC.key)
ON TableA.keyOfB = TableB.key
WHERE TableA.key = aValue
Flipping to RIGHT OUTER:
SELECT TableA.* FROM TableB
INNER JOIN TableC ON TableB.keyOfC = TableC.key
RIGHT OUTER JOIN TableA ON TableA.keyOfB = TableB.key
WHERE TableA.key = aValue
NOTE: Forgive me if this is doesn't work, I haven't touched SqlServer since version 7.
This is behaving exactly as it should. Your link with TableC is through TableB so the link will not be connected if no TableB record.
Changing INNER JOIN to LEFT OUTER as well - although it is really an inner as far as the data concerned.
If you run query without INNER JOIN, there will be all records with TableB.key null, right? So next INNER JOIN can't find any matching record, that's why there is no result.
Use a virtual table for (B+C) join.
EDIT: Something like:
SELECT TableA.* FROM TableA
LEFT OUTER JOIN
(select key from TableB INNER JOIN TableC ON TableB.keyOfC = TableC.key) as TableBC
ON TableA.keyOfB = TableBC.key
where TableA.key = aValue
Here is the code as an example of using left out join for both table b and c.
declare #TableA table (Adata1 char(2), Adata2 char(2))
declare #TableB table (Bdata1 char(2), Bdata2 char(2))
declare #TableC table (Cdata1 char(2), Cdata2 char(2))
;Insert #TableA
Select 'A', 'A' union all
Select 'B', 'B' union all
Select 'C', 'C'
;Insert #TableB
Select 'Ab', 'Ab' union all
Select 'B', 'B' union all
Select 'C', 'C'
;Insert #TableC
Select 'A', 'A' union all
Select 'B', 'B' union all
Select 'Cb', 'Cb'
--Select * From #TableA
--Select * From #TableB
--Select * From #TableC
Select * from #TableA
LEFT OUTER JOIN #TableB on Adata1 = Bdata1
LEFT OUTER JOIN #TableC on Bdata1 = Cdata1
Results are:
Adata1 Adata2 Bdata1 Bdata2 Cdata1 Cdata2
A A NULL NULL NULL NULL
B B B B B B
C C C Cb NULL NULL