I have a dataset in SQl which includes huge numbers of tables (more than 2000). Within these tables, I have a main table called ‘main_table’, that includes some parameters and one of them is the key named ‘id’. I have also a table called ‘Tables_name’, which consists of the name of the tables (around 500 tables name) that I want to join to the main table (main_table). Each table has two parameters (id and value).
Basically I want to left join all the tables (in the dataset) which their names are in ‘Tables_name’, based on their ‘id’. I need a query that automatically join those tables (and creat a new table having all parameters from the main_table and values of those joint tables) based on thier key which is ‘id’. They all have the ‘id’ as the key parametrs.
main_table: id, name, date, category, age, brand, number Tables_name: tablxcd tableasd tablefgd .. .. .. tablxcd: id,value tablasd: id,value tablegd: id,value
My desired table should be like this:
output_table: id, name, date, category, age, brand, number, tablxcd_value, tablasd_value, ...
It should be left join, because there might be some ids which are not matched for all tables, so in the output table the values of those rows which are not matched should be zero. I have tried this :
SELECT mn.Id,mn.name ,mn.Date ,mn.brand ,mn.category ,xcs.value as tablxcd_value ,asd.value as tablasd_value FROM [mydatabase].[dbo].[main_table] mn LEFT JOIN [mydatabase].[dbo]. [tablxcd] xcs ON mn.Id=xcd.Id LEFT JOIN [mydatabase].[dbo].[tablasd] asd ON asd.Id=mn.Id where mn.Date > '2018-01-01'
But this is manual, and some how it is not possible to put all the 500 tables’ name here.
Advertisement
Answer
This will assemble a dynamic query from a list of tables. It assumes that Tables_name has an IDENTITY. If it does not, then create a temp table with an IDENTITY and use it instead. It also assumes that the tables names do not contain special characters or use reserved words.
DECLARE @qry NVARCHAR(MAX), @strJoins NVARCHAR(MAX) = '', @strColumns NVARCHAR(MAX) = '' DECLARE @i SMALLINT = 1, @imax SMALLINT = (SELECT COUNT(*) FROM dbo.tables_name) WHILE @i <= @imax BEGIN SELECT @strColumns = @strColumns + CHAR(10) + ', ' + name + '.value as ' + name + 'value' FROM dbo.tables_name WHERE Id = @i SELECT @strJoins = @strJoins + CHAR(10) + 'LEFT JOIN ' + name + ' ON ' + name + '.Id = main.Id' FROM dbo.tables_name WHERE Id = @i SET @i += 1 END SELECT @qry = 'SELECT main.* ' + @strColumns + CHAR(10) + 'FROM main ' + @strJoins PRINT @qry