Using Joins to get all data from left table - sql-server

I have two tables as shown below.
Id Name Id Status
-------- -------------------
1 A 1 Approved
2 B 6 Approved
3 C 4 Pending
4 D 1 Approved
5 E 1 Pending
6 F 3 Pending
5 Rejected
Now this is how I want the output to be:
Id Name Status
-------------------
1 A Pending
2 B
3 C Pending
4 D Pending
5 E
6 F
I have tried using left join but I am getting multiple rows.
select t1.ID,Name,Status from t1 left join t2 on t1.id=t2.id
and if I add where Status=pending i am getting only ids 1 and 3.
Here are the queries i tried:
select distinct t1.id,name,status from t1 left join t2 on t1.id=t2.id (this gives me duplicate records i.e id 1 is occurs twice with approved and pending)
and also
select distinct t1.id,name,status from t1 left join t2 on t1.id=t2.id where t2.status='pending' (gives me only 1,3 and 4)
Could any one help me,
Thanks in advance.

To include all rows from T1 and only those from T2 with status = 'pending' move the condition into the ON clause SQL Fiddle
SELECT t1.ID,
Name,
Status
FROM t1
LEFT JOIN t2
ON t1.id = t2.id
AND t2.status = 'pending'
To only return one row per id in the event of dupes you could do (Fiddle)
WITH CTE AS
(
SELECT DISTINCT id, Status
FROM T2
WHERE Status = 'Approved'
)
SELECT t1.ID,
Name,
Status
FROM t1
LEFT JOIN CTE
ON t1.id = CTE.id

Related

SQL Server query about joining 2 table with union

I have two tables T1 and T2, both of them contain a column ID and value.
I need to join T1 and T2 into T3 by means of ID.
T3 should contain columns ID, T1Value, and T2Value.
The main requirement is, ID of T1 and T2 is possible not mapped
T1:
ID VALUE
-----------
1 hi
2 hello
T2:
ID VALUE
----------
2 kitty
3 dog
Then, T3 should be
ID T1VALUE T2VALUE
----------------------
1 hi
2 hello kitty
3 dog
Is it possible to achieve this without using pivot table, or temp table (ideally should be a single executable query)?
Thanks.
You can use FULL OUTER JOIN
SELECT ID = COALESCE(T1.ID, T2.ID),
T1VALUE = T1.VALUE,
T2VALUE = T2.VALUE
FROM T1
FULL OUTER JOIN T2
ON T1.ID = T2.ID
There are lots of example on FULL OUTER JOIN . just search for it
Another way is to use UNION ALL
SELECT T1.ID, T1VALUE = T1.VALUE, T2VALUE = NULL
FROM T1
UNION ALL
SELECT T2.ID, T1VALUE = NULL, T2VALUE = T2.VALUE
FROM T2

Joining Tables with Criteria

How do I create an MSSQL query that joins TableA with TableB using the ID field, however I want it to join on ID record that has the highest value in the Number column?
TableA
ID
1
2
3
4
TableB
ID Number
1 1
1 2
1 3
2 1
3 1
3 2
4 1
4 2
4 3
I would want this as my output
TableJoined
ID Number
1 3
2 1
3 2
4 3
Is there a way to use a LEFT JOIN to achieve this or using max()?
Both. Use aggregation on the left join.
Select t1.id, max(t2.number)
From table1 t1
Left join table2 t2 on t1.id= t2.id
Group by t1.id;
You can query as below:
Select a.Id, Number from #a a join
(
Select top(1) with ties * from #b
order by row_number() over(partition by id order by number desc)
) b on a.id = b.id
Select A.Id, Max(Number) MaxNo from A
join B on A.Id=B.Id
Group by A.Id
create table #a(
id int
)
go
create table #b(
id int,
number int
)
go
insert into #a values(1),(2),(3),(4)
insert into #b values(1,1),(1,2),(1,3),(2,1),(3,1),(3,2),(4,1),(4,2),(4,3)
select #b.id,MAX(number) as maximum
from #b left outer join #a on #b.id=#a.id
group by #b.id

t-sql join help

Table_A
TxID RelatedTxID
-------------------
1 NULL
2 NULL
3 1
Table_B
OrderID TxID OrderDescription
-----------------------------------
1 1 Description_1
2 2 Description_2
I want to get an output which will give me order description for the transaction. But if the transaction does not have an order description I want to display it's related transaction's order description (Related transaction will always have an order description)
Output
TxID RelatedTxID OrderDescription
------------------------------------
1 NULL Description_1
2 NULL Description_2
3 1 Description_1
I am thinking of something like below but stuck at what should come in the ISNULL expression.
select
a.TxID,
a.RelatedTxID,
ISNULL(b.OrderDescription, <<get its related transaction's order description>>)
from Table_A a
left outer join Table_B b
on a.TxID = b.TxID
Thanks
select
a.TxID,
a.RelatedTxID,
ISNULL(b1.OrderDescription, b2.OrderDescription)
from Table_A a
left outer join Table_B b1 on a.TxID = b1.TxID
left outer join Table_B b2 on a.RelatedTxID = b2.TxID

problem with join SQL Server 2000

I have 3 tables -
Items,
Props,
Items_To_Props
i need to return all items that match all properties that i send
example
items
1
2
3
4
props
T1
T2
T3
items_to_props
1 T1
1 T2
1 T3
2 T1
3 T1
when i send T1,T2 i need to get only item 1
SELECT T.itemId
FROM (SELECT itemId, count(distinct prop) propCount
FROM items_to_props
WHERE prop in ('T1', 'T2')
GROUP BY itemId) T
WHERE T.propCount = 2
If you don't know how many props you have, you can create a temp table #P(prop), populate it with your props and run the folowing query (will do the same thing):
SELECT T.itemId
FROM (SELECT i.itemId, count(distinct p.prop) propCount
FROM items_to_props i
JOIN #P p on i.prop = p.prop
GROUP BY i.itemId) T
WHERE T.propCount = (SELECT COUNT(DISTINCT prop) FROM #P)
It is correct that you only get one row for T2, you should get 3 for T1

Limited T-SQL Join

This should be simple enough, but somehow my brain stopped working.
I have two related tables:
Table 1:
ID (PK), Value1
Table 2:
BatchID, Table1ID (FK to Table 1 ID), Value2
Example data:
Table 1:
ID Value1
1 A
2 B
Table 2:
BatchID Table1ID Value2
1 1 100
2 1 101
3 1 102
1 2 200
2 2 201
Now, for each record in Table 1, I'd like to do a matching record on Table 2, but only the most recent one (batch ID is sequential). Result for the above example would be:
Table1.ID Table1.Value1 Table2.Value2
1 A 102
2 B 201
The problem is simple, how to limit join result with Table2. There were similar questions on SO, but can't find anything like mine. Here's one on MySQL that looks similar:
LIMITing an SQL JOIN
I'm open to any approach, although speed is still the main priority since it will be a big dataset.
WITH Latest AS (
SELECT Table1ID
,MAX(BatchID) AS BatchID
FROM Table2
GROUP BY Table1ID
)
SELECT *
FROM Table1
INNER JOIN Latest
ON Latest.Table1ID = Table1.ID
INNER JOIN Table2
ON Table2.BatchID = Latest.BatchID
SELECT id, value1, value2
FROM (
SELECT t1.id, t2.value1, t2.value2, ROW_NUMBER() OVER (PARTITION BY t1.id ORDER BY t2.BatchID DESC) AS rn
FROM table1 t1
JOIN table2 t2
ON t2.table1id = t1.id
) q
WHERE rn = 1
Try
select t1.*,t2.Value2
from(
select Table1ID,max(Value2) as Value2
from [Table 2]
group by Table1ID) t2
join [Table 1] t1 on t2.Table1ID = t1.id
Either GROUP BY or WHERE clause that filters on the most recent:
SELECT * FROM Table1 a
INNER JOIN Table2 b ON (a.id = b.Table1ID)
WHERE NOT EXISTS(
SELECT 1 FROM Table2 c WHERE c.Table1ID = a.id AND c.BatchID > b. BatchID
)

Resources