Skip to content
Advertisement

Creating Dynamic SQL Query to join multiple tables?

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
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement