I have two tables as below that I am looking to join dynamically using the ColVal in TMaster with ColName in TMaster which is the name of the column to match with in TTable1.
TMaster:
TTable1:
So, final result would be the data from TTable1 that matches the colName and ColVal in TMaster. How do I achieve this?
select tt.Name
from TMaster tm
join TTable1 tt on TMaster.ColVal = tt.[ColName from TMaster should be used here]
Why not :
SELECT tt.Name
FROM TMaster AS tm
JOIN TTable1 AS tt
ON tm.ColVal = CASE ColVal
WHEN 1 THEN tt.Col1
WHEN 2 THEN tt.Col2
WHEN 3 THEN tt.Col3
END
You can formulate your query in the following manner
SELECT tt.Name
FROM TMaster tm
JOIN TTable1 tt ON
tm.ColName = 'Col1' AND tm.ColVal = tt.Col1 OR
tm.ColName = 'Col2' AND tm.ColVal = tt.Col2 OR
tm.ColName = 'Col3' AND tm.ColVal = tt.Col3 OR
....
It's not going to be very performant though.
If you do not even know your column names (why that should be, I don't know) then you need dynamic SQL.
DECLARE @sql nvarchar(max) = '
SELECT tt.Name
FROM TMaster tm
JOIN TTable1 tt ON
' +
(
SELECT STRING_AGG(CAST(
' tm.ColName = ' + QUOTENAME(c.name, '''') + ' AND tm.ColVal = tt.' + QUOTENAME(c.name)
AS nvarchar(max)), N' OR
'
)
FROM sys.columns
WHERE OBJECT_NAME(object_id) = 'TTable1'
);
PRINT @sql; -- for testing
EXEC sp_executesql @sql;
One solution is to use a query such as this:
SELECT TMaster.*, x.Name
FROM TTable1
CROSS APPLY (VALUES
('ID', ID, Name),
('ID2', ID2, Name),
('ID3', ID3, Name),
('ID4', ID4, Name)
) AS x(ColName, ColVal, Name)
JOIN TMaster ON TMaster.ColName = x.ColName AND TMaster.ColVal = x.ColVal
Or this variant which could produce a smaller number of rows:
FROM (
SELECT 'ID', ID, Name FROM TTable1 WHERE ID IS NOT NULL UNION ALL
SELECT 'ID2', ID2, Name FROM TTable1 WHERE ID2 IS NOT NULL UNION ALL
SELECT 'ID3', ID3, Name FROM TTable1 WHERE ID3 IS NOT NULL UNION ALL
SELECT 'ID4', ID4, Name FROM TTable1 WHERE ID4 IS NOT NULL
) AS x(ColName, ColVal, Name)
The list of (column name, column value) pairs should contain all columns that exist in TTable1; possibly restricted to the names that exist in TMaster.ColName
.
If the datatype of columns ID, ID2, ID3, ... is different you need to match the datatype x.ColVal
to match that of TMaster.ColVal
:
CROSS APPLY (VALUES
('ID', CAST(ID AS VARCHAR(200)), Name),
('ID2', CAST(ID2 AS VARCHAR(200)), Name),
Finally, the (column name, column value) pairs could instead be converted to a view (which could be materialized I think) and then you can join with it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.