14
SELECT var1,var2,var3,table_name 
FROM table1 LEFT JOIN table_name on var3=table_name.id

Meaning I want to dynamically left join table, depending on value of table_name from table1, since var3 is taken from there.

But the above query results in

table table_name does not exist

My mistake of mysql limitation?

codaddict
  • 445,704
  • 82
  • 492
  • 529
selytch
  • 535
  • 2
  • 9
  • 24
  • I don't think you can do this. You will likely need to pass the table name in to a stored procedure if you want this type of functionality or redesign what you're trying to do. – spig Sep 05 '10 at 14:39
  • 1
    It's not a MySQL limitation. More like SQL limitation if you can call it that, but I wuold rather say, it's an indication that something's wrong with your database design. – Mchl Sep 05 '10 at 15:01
  • Main table contains objects. Each object can have attributes. There are separate tables for each attribute listing possible values - values can be very long (several hundred chars) and there are many possible values (thousands). So the main table has 2 fields per attribute: attr_table_name, attr_table_id - to save space and to allow attribute name modification. When query is run, I return actual attribute value, not the id, thats why I need LEFT JOIN and dynamic table naming. How else would you design the DB? – selytch Sep 13 '10 at 04:11

2 Answers2

14

Table names, as well as column names, can't be dynamic in an SQL query. So you have to apply your logic programmatically, using 2 queries, or with a stored procedure, see an example here: http://forums.mysql.com/read.php?98,126506,126598#msg-126598

Damien
  • 2,254
  • 1
  • 22
  • 30
4

Another way is to unite all tables with a union query:

SELECT *, 44 as table_origin FROM `Table_44`
UNION ALL
SELECT *, 58 as table_origin FROM `Table_58`;

You could even prepare that as view:

CREATE VIEW `AllTheTables` AS
SELECT *, 42 as table_origin FROM `Table_42`
UNION ALL
SELECT *, 44 as table_origin FROM `Table_44`
UNION ALL
SELECT *, 58 as table_origin FROM `Table_58`
UNION ALL
SELECT *, 69 as table_origin FROM `Table_69`;

And thus query it safely:

SELECT * FROM AllTheTables WHERE table_origin IN (44,58) AND something = 'foobar';
-- or --
SELECT * FROM AllTheTables WHERE table_origin = 42 AND something = 'the question';

In your exact case it could look like this:

SELECT var1, var2, var3, table_name 
FROM table1 LEFT JOIN AllTheTables ON table1.var3=AllTheTables.table_origin
luckydonald
  • 5,976
  • 4
  • 38
  • 58