SQL Server Join 2 Tables with Relationship in 3rd Table - sql-server

I have 3 tables:
Table_A
tblA_ID | tblA_Key | tblA_Info
1 2A ABC
Table_B
tblB_ID | tblB_to_A_Relations | tblB_Info
1 1 XYZ
2 1 DEF
3 1 QWE
4 1 NOP
Table_C
tblC_ID | tblC_to_A_Relations | tblC_Info
1 2A 999
2 2A 888
3 2A 777
Table_B and Table_C doesn't have direct relationship but I wanted to join them by using their relationships on Table_A. This is what I've tried so far.
SELECT DISTINCT
b.*,
c.tblC_Info,
FROM Table_B b
LEFT JOIN (SELECT tblA_ID, tblA_Key FROM Table_A
WHERE tblA_Key = #parameter)a
ON a.tblA_ID = b.tblB_to_A_Relations
LEFT JOIN Table_C c
ON c.tblC_to_A_Relations = a.tblA_Key
ORDER BY b.tblB_ID ASC
Somehow outputs:
ResultSet
tblB_ID | tblB_to_A_Relations | tblB_Info | tblC_Info
1 1 XYZ 999
1 1 XYZ 888
1 1 XYZ 777
2 1 DEF 999
2 1 DEF 888
2 1 DEF 777
3 1 QWE 999
3 1 QWE 888
3 1 QWE 777
4 1 NOP 999
4 1 NOP 999
4 1 NOP 999
But my expected output is something like this:
ExpectedOutput
tblB_ID | tblB_to_A_Relations | tblB_Info | tblC_Info
1 1 XYZ NULL
2 1 DEF 999
3 1 QWE 888
4 1 NOP 777
Surely missing something. Any help would really be appreciated!
EDIT
After more inspection of the existing tables and data, it appears that the above results are already filtered records and luckily, after tedious tracing, I found a field that somehow tells them they are unique from the other records.
Table_B
tblB_ID | tblB_to_A_Relations | tblB_Info | **tblB_Values**
1 1 XYZ AAA
2 1 DEF BBB
3 1 QWE CCC
4 1 NOP DDD
Table_C
tblC_ID | tblC_to_A_Relations | tblC_Info | **tblC_Values**
1 2A 999 BBB
2 2A 888 CCC
3 2A 777 DDD
At first, I made a mistake to ignore these fields not knowing the answer was there all along.
Going to post my answer.

Declare #A table
(
tbla_ID int,
tblA_Key varchar(2),
tbla_info varchar(3)
)
Declare #B table
(
tblb_ID int,
tblB_to_A varchar(2),
tblB_info varchar(3)
)
Declare #C table
(
tblb_ID int,
tblC_to_A varchar(2),
tblB_info int
)
Insert into #A
Select 1,'2A','ABC'
Insert into #B
Select 1,1,'XYZ'
union
Select 2,1,'DEF'
union
Select 3,1,'QWE'
union
Select 4,1,'NOP'
Insert into #c
Select 1,'2A',999
UNION
Select 2,'2A',888
UNION
Select 3,'2A',777
Select B.*,C.tblB_info from #A A
join #B B
on A.tbla_ID=B.tblB_to_A
left join #C C
on B.tblb_ID=C.tblb_ID and A.tbla_key=C.tblC_to_A
Null value belongs to 4th row exactly equal to 'NOP'

The workaround I did:
Create a temporary container and update unique keys from Table_B to Table_C in a modified column of a temporary table with reference to Table_A.
Here's what the temporary table looked like:
TempTbl
tblC_ID | Modified_Col | tblC_to_A_Relations | tblC_Info
1 2 2A 999
2 3 2A 888
3 4 2A 777
Managed to get this resultset using a copy of Table_C (#TempTbl)
UPDATE #TempTbl
SET
#TempTbl.Modified_Col = #TempTbl_B.tblB_ID
FROM
#TempTbl
INNER JOIN
#TempTbl_B
ON
#TempTbl.tblB_Values = #TempTbl_B.tblC_Values
And pulled left join for final result.
SELECT * FROM Table_B x
LEFT JOIN #TempTbl y
ON x.tblB_ID = y.Modified_Col
PS: I really do apologize how horrible the workaround was.

Related

Convert a row with multiple quantity to multiple rows of single quantity while joining another table with partial data

I have 2 tables, one with the ID and its count and the other with the names belonging to the respective IDs. They need to be joined so that the end result is a table with count of 1 in each row and the respective names next to them. Note that the number of names in table 2 is less than the count in table 1 for the same ID in some cases.
Table 1
ID | Count
-----------
100 | 3
101 | 2
102 | 4
Table 2
ID | Name
----------
100 | abc
100 | def
101 | ghi
101 | jkl
102 | mno
102 | pqr
102 | stu
Result
ID | Count | Name
------------------
100 | 1 | abc
100 | 1 | def
100 | 1 |
101 | 1 | ghi
101 | 1 | jkl
102 | 1 | mno
102 | 1 | pqr
102 | 1 | stu
102 | 1 |
I'm using TSQL for this and my current query converts table 1 into multiple rows in the result table; then it inserts individual names from table 2 into the result table through a loop. I'm hoping there must be a simpler or more efficient way to do this as the current method takes considerable amount of time. If there is, please let me know.
The first thing that comes to mind for me involves using a Number table, which you could create (as a one-time task) like this:
CREATE TABLE numbers (
ID INT
)
DECLARE #CurrentNumber INT, #MaxNumber INT
SET #MaxNumber = 100 -- Choose a value here which you feel will always be greater than MAX(table1.Count)
SET #CurrentNumber = 1
WHILE #CurrentNumber <= #MaxNumber
BEGIN
INSERT INTO numbers VALUES (#CurrentNumber)
SET #CurrentNumber = #CurrentNumber + 1
END
Once you have a numbers table, you can solve this problem like this:
SELECT one.ID,
1 AS [Count],
ISNULL(two.Name,'') AS Name
FROM table1 one
JOIN numbers n ON n.ID <= CASE WHEN one.[Count] >= (SELECT COUNT(1) FROM table2 two WHERE one.ID = two.ID)
THEN one.[Count]
ELSE (SELECT COUNT(1) FROM table2 two WHERE one.ID = two.ID)
END
LEFT JOIN (SELECT ID,
Name,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY ID) AS RecordNo
FROM table2) two ON one.ID = two.ID
AND two.RecordNo = n.ID

Compare the values of column in SQL Server

Table_1 columns are:
======================
A B
======================
100 4
-----------
101 2
101 3
101 4
-----------
102 6
-----------
103 7
-----------
104 2
104 3
104 4
-----------
105 2
-----------
106 4
-----------
107 3
--------------------------------
Now I have input B parameter like '6' or '2,3,4'.
I want to get a result like this:
if input B parameter is '6', then output should be:
======================
A B
======================
102 6
If input B parameter is '2,3,4', then output should be:
======================
A B
======================
101 2
101 3
101 4
-----------
104 2
104 3
104 4
Just select the needed columns:
SELECT A, B
FROM Table_1
WHERE B IN (2,3,4)
EDIT:
If you need them only if all params are present
SELECT A, B
FROM Table_1
WHERE A IN (SELECT A FROM Table_1 WHERE B = 2) AND A IN (SELECT A FROM Table_1 WHERE B = 3) AND A IN (SELECT A FROM Table_1 WHERE B = 4)
You can try this one, for your specific requirement -
-- the last digit after = i.e. 3 should be replaced by number of inputs in check for our case it is 3 for (2,3,4)
SELECT A,B FROM Table_1 AS tbl1 WHERE B IN (2,3,4) AND (select COUNT(1) FROM Table_1 AS tbl2 WHERE B IN (2,3,4) AND tbl1.A = tbl2.A)
= 3
Please, have a look.
Thanks!
SELECT A
,B
FROM table_1
WHERE A IN (
SELECT A
FROM table_1
WHERE B = 2
)
AND A IN (
SELECT A
FROM table_1
WHERE B = 3
)

Uniquely left join many to many table

I am using sqlserver and I have two table which contains below data. I need to select those matched rows without duplicate.
Table_A:
A_ID | Item_ID
--------------------
1 | 101
2 | 101
3 | 103
4 | 103
5 | 199
Table_B:
B_ID | Item_ID
--------------------
11 | 101
12 | 101
13 | 102
14 | 103
15 | 103
16 | 103
Expected Result:
A_ID | Item_ID | B_ID
----------------------
1 | 101 | 11
2 | 101 | 12
3 | 103 | 14
4 | 103 | 15
I tried:
SELECT A_ID, a.Item_ID, B_ID FROM Table_A a LEFT JOIN
Table_B b ON a.Item_ID = b.Item_ID
But it show all the possible records.
How can i display the expected result above?
Based on the result set you gave you want one unique record from B for each A, ignoring records in A for which there is no corresponding record in B. The following will work:
SELECT
AValues.A_ID,
AValues.Item_ID,
BValues.B_ID
FROM
(SELECT
A_ID,
Item_ID,
ROW_NUMBER() OVER(PARTITION BY Item_ID ORDER BY A_ID) ARowID
FROM
Table_A) AValues
INNER JOIN (SELECT
B_ID,
Item_ID,
ROW_NUMBER() OVER(PARTITION BY Item_ID ORDER BY B_ID) BRowID
FROM
Table_B) BValues ON AValues.Item_ID = BValues.Item_ID AND AValues.ARowID = BValues.BRowID

Join unrelated tables

I want to join these two unrelated tables:
table 1
id name age
-- ---- ---
1 a 9
2 b 11
3 c 10
table 2
id school address
-- ------ -------
1 aa abc
1 aa efg
3 bb hij
Desired results:
id school address age name
-- ------ ------- --- ----
1 aa abc 9 a
1 aa efg 9 a
2 NULL NULL 11 b
3 bb hij 10 c
SELECT t1.id, t2.school, t2.address, t1.age, t1.name
FROM dbo.table1 AS t1
LEFT OUTER JOIN dbo.table2 AS t2
ON t1.id = t2.id
ORDER BY t1.id;

need result of two table sql query

I have a two sql server tables that contains data like this
Table a
catId | catname | Isdeleted
-------------------------------------------------
1 ABC 0
2 DEF 0
3 GHI 0
and another table is
Table B
id | Name | Name1 | Catid
--------------------------------------------------
1 abc aaaa 1
2 def bbbb 1
3 ghi gggg 2
4 jkl jjjj 2
5 xyz xxxxx 3
Now I want result in this format
catname from table a and all the fields from table b according to
catid of table a and catname should be distinct.
Please help me
Write your query like this :
SELECT DISTINCT a.catname, b.* FROM a INNER JOIN b
ON a.catid = b.catid WHERE catid = [catid]
If you have multiple records in table b for each catid or catname, you will see multiple records with same catname in result. there is no other choice unless catname be unique in both tables a and b.

Resources