Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MySQL Inner Join table based on column value

Tags:

sql

mysql

Suppose I have a table 'stats' with the following structure:
tableName | id | pageViews
The tableName column corresponds to separate tables in the database.

When running a query against "stats", what would be the best way to inner join against the tableName column result to get each table's data?
I was thinking of running dynamic selects in a foreach and then merging the results. E.g.:

foreach($tableNames as $tableName) {
    $sql = "SELECT      *
            FROM        stats s
            INNER JOIN  $tableName tbl ON s.id = tbl.id
            WHERE       tableName = '$tableName'";
}
like image 857
jexx2345 Avatar asked Dec 27 '22 23:12

jexx2345


2 Answers

To have all tables' statistics, you can use a UNION, with 2 or more selects, one for each table:

( SELECT s.*
       , table1.title AS name      --or whatever field you want to show
  FROM stats s
    JOIN $tableName1 table1
      ON s.id = table1.id
  WHERE tableName = '$tableName1'
)
UNION ALL
( SELECT s.*
       , table2.name AS name      --or whatever field you want to show
  FROM stats s
    JOIN $tableName2 table2
      ON s.id = table2.id
  WHERE tableName = '$tableName2'
)
UNION ALL
( SELECT s.*
       , table3.lastname AS name      --or whatever field you want to show
  FROM stats s
    JOIN $tableName3 table3
      ON s.id = table3.id
  WHERE tableName = '$tableName3'
)
;

Using Winfred's idea with LEFT JOINs. It produces different results, e.g. every field from the other tables is output in it's own column (and many NULLs occur).

SELECT s.*
     , table1.title      --or whatever fields you want to show
     , table2.name
     , table3.lastname   --etc
FROM stats s
  LEFT JOIN $tableName1 table1
    ON s.id = table1.id
      AND s.tableName = '$tableName1'
  LEFT JOIN $tableName2 table2
    ON s.id = table2.id
      AND s.tableName = '$tableName2'
  LEFT JOIN $tableName3 table3
    ON s.id = table3.id
      AND s.tableName = '$tableName3'
--this is to ensure that omited tables statistics don't appear
WHERE s.tablename IN
   ( '$tableName1'
   , '$tableName2'
   , '$tableName3'
   )
;
like image 68
ypercubeᵀᴹ Avatar answered Jan 15 '23 05:01

ypercubeᵀᴹ


Do you have the luxury to join all tables first,and process it afterwards?

SELECT *
    FROM stats s
    LEFT OUTER JOIN tbl1 ON s.id = tbl.id
    LEFT OUTER JOIN tbl2 ON s.id = tbl2.id

Then you take the value you need in your program afterwards?

You should try to minimise the number of queries you made to your database, try to do it in one go if possible.

Otherwise, think about Stored Procedures etc

This is one easy way of doing it(with overheads), Im sure others will help you out too.

like image 44
Winfred Avatar answered Jan 15 '23 07:01

Winfred