基于列值的MySQL内部连接表

5
假设我有一个名为“stats”的表,其结构如下:
tableName | id | pageViews
tableName列对应于数据库中的不同表。
当针对“stats”运行查询时,最好的方法是什么来内部连接tableName列结果以获取每个表的数据?我考虑在foreach中运行动态选择,然后合并结果。例如:
foreach($tableNames as $tableName) {
    $sql = "SELECT      *
            FROM        stats s
            INNER JOIN  $tableName tbl ON s.id = tbl.id
            WHERE       tableName = '$tableName'";
}

你说“tableName列对应于数据库中的单独表”。那么“id”对应什么?我理解得对,这个stats表包含了每个表的每一行的统计信息吗?因此,stats中的每一行都为“tableName”表中的“id”存储了“pageViews”? - ypercubeᵀᴹ
2个回答

7

要获取所有表的统计信息,您可以使用UNION,使用2个或多个SELECT语句,每个SELECT语句对应一个表:

( 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'
)
;

使用Winfred的想法,采用LEFT JOIN。它会产生不同的结果,例如,其他表中的每个字段都会在自己的列中输出(并且会出现许多NULL)。
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'
   )
;

你好。谢谢回复。实际上在你回答之前我已经采用了这种方法,但还是感谢你的确认。 - jexx2345
谢谢。实际上,可以采用LEFT JOIN的方式来实现Winifred的想法,并且它会产生略微不同的结果。 - ypercubeᵀᴹ

3

您是否有足够的时间将所有表格连接在一起并进行后续处理?

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

那么你之后在程序中需要使用的值是什么?

尽可能减少向数据库发出的查询请求,如果可能的话,尝试一次性完成。

否则,请考虑使用存储过程等方法。

这是一种简单的方法(带有开销),我相信其他人也会帮助你。


谢谢你的建议。我打算采用你的建议,使用左外连接。那么你认为一个包含n个连接的查询比不使用存储过程的多个查询更有效吗? - jexx2345
这取决于您要提取多少数据。如果您只添加了1列且n相对较小,则这是一个可接受的解决方案。否则,您可以考虑如何使用单个查询返回所有n行,然后在内部处理这些n行,或者如果表格不适用于您的情况,则转而使用SP和更高级的数据结构。 - Winfred
我认为这个查询不会显示正确的结果。例如,它将把tbl1中id=1的行与tbl2中相同的行(id=1)相关联。 - ypercubeᵀᴹ
你好。是的,我也遇到了同样的问题。不过我使用 Union 方法得到了我想要的结果。 - jexx2345

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接