按表类型引用的MySQL辅助表

按表类型引用的MySQL辅助表,mysql,Mysql,我有一个“posts”表,其中包含post_类型和对应表的主键,每个post_类型都有一个对应表 我想从相应的表中检索数据,就像填充社交提要样式墙中的条目一样。e、 g.最终数据可能无法打包为JSON实体 以下是一些屏幕截图来说明我的数据库表: ` 帖子 ` 游戏 ` 成就 ` 视频 我是MySQL查询新手,因此我有几个考虑因素,我想知道使用MySQL的CASE语句是否可以实现这一点。我添加了一段伪代码,希望能说明我的想法 SELECT * FROM posts

我有一个“posts”表,其中包含post_类型和对应表的主键,每个post_类型都有一个对应表

我想从相应的表中检索数据,就像填充社交提要样式墙中的条目一样。e、 g.最终数据可能无法打包为JSON实体

以下是一些屏幕截图来说明我的数据库表:

`

帖子

`

游戏

`

成就

`

视频

我是MySQL查询新手,因此我有几个考虑因素,我想知道使用MySQL的CASE语句是否可以实现这一点。我添加了一段伪代码,希望能说明我的想法

SELECT * FROM posts
            CASE 
                WHEN posts.post_type = 'game' THEN 
                    INNER JOIN games ON (games.game_id = posts.origin_id)
                WHEN posts.post_type = 'achievement' THEN
                    INNER JOIN achievements ON (achievements.achievement_id = posts.origin_id)
                WHEN posts.post_type = 'event' THEN
                    INNER JOIN events ON (event.event_id = posts.origin_id)
            END;
或者,如果这是不可能的、有效的或实用的,那么我真的希望有一种更有效的替代方法。我用一些示例数据库表等创建了一个SQLFIDLE(不是100%准确,只是为了测试)

我被告知的一个选项是使用左连接,我正在这里进行试验:

但是,我无法在不丢失/损坏数据的情况下使用PHP有效地获取实体数据。很明显,第二个实体中缺少实体数据,甚至还有其他数据,例如缺少创建的和更新的条目,以及添加的条目

我尝试使用以下PHP例程从左连接中删除空值:

最后但并非最不重要的一点是,下面的一位评论者提供了一种使用内部联接和联合的替代方法,但我一直无法实现这一点:

希望很明显,我希望得到的结果是一组连续的post实体,在JSON格式的列表中有自己的相关表数据


关于

使用
子查询
而不是
连接
。对于特定的
id
,如果
subquery
返回多行
,则不要使用
subquery

检查此SQL FIDLE:


希望此查询对您有所帮助。

使用
子查询
而不是
加入
。对于特定的
id
,如果
subquery
返回多行
,则不要使用
subquery

检查此SQL FIDLE:


希望此查询对您有所帮助。

尝试此更新您的小提琴:

编辑

从mysql php读取数据:

  $post = array();
    if ($result = $mysqli->query($query)) {    
        /* fetch object array */
        while ($obj = $result->fetch_object()) {
            array_push($post,$obj);
        }
     }

vardump($post);
在每一行中返回
null
的元素很少

要从数组中删除
NULL
empty
字段:

php:

foreach($array as &$value) {
    $value = array_filter($value, function($v) {    return ! empty( $value ); });
}

 // $array = array_map('array_filter', $array);

请参阅:

尝试此更新您的小提琴:

编辑

从mysql php读取数据:

  $post = array();
    if ($result = $mysqli->query($query)) {    
        /* fetch object array */
        while ($obj = $result->fetch_object()) {
            array_push($post,$obj);
        }
     }

vardump($post);
在每一行中返回
null
的元素很少

要从数组中删除
NULL
empty
字段:

php:

foreach($array as &$value) {
    $value = array_filter($value, function($v) {    return ! empty( $value ); });
}

 // $array = array_map('array_filter', $array);

请参阅:

您认为可以使用SELECT语句检索数据,这意味着表格游戏、成就和事件包含一组公共(子)属性(尽管表格在“\u id”字段上有不同的前缀,但数据域在每种情况下都是相同的)。在没有任何进一步信息的情况下,这些表不应被设计为单独的表,而应使用一个带有“type”属性的表,以及详细说明任何非公共属性的单独表。事实上,如果“posts”表中包含的所有内容都是包含数据的表的id和标识符,那么此时它就变得多余了—您应该有1个表,而不是4个表

除其他问题外,您不会遇到上述问题

如果您已经围绕此设计实现了一个系统,并且解决问题的成本太高,那么您可以通过以下方式应用解决方法:

SELECT *
FROM posts p
INNER JOIN (
   SELECT a.achievent_id AS common_id, .....
   FROM achievements a
   UNION
   SELECT g.game_id, .....
   FROM games g
   UNION
   SELECT e.event_id, ....
   FROM events e
 ) AS ilv
   ON p.id=ilv.id
在哪里。。。表示公共属性

但是除了没有提供表结构的详细信息之外,您也没有告诉我们查询将如何过滤——我怀疑您是否希望每次运行查询时都检索整个数据集。如何实现过滤将对性能产生很大影响

如果通过对posts表进行筛选(即使用您没有告诉我们的某些属性),行数减少最多,则选择联接的并集(而不是联接到并集)将更有效:

SELECT *
FROM posts p
INNER JOIN
achievements a
ON p.id=a.achievement_id
WHERE p.user=?
UNION
SELECT *
FROM posts p
INNER JOIN
events e
ON p.id=e.evet_id
WHERE p.user=?
UNION
SELECT *
FROM posts p
INNER JOIN
games g
ON p.id=g.game_id
WHERE p.user=?

您认为可以使用SELECT语句检索数据,这意味着表games、Acquisition和events包含一组公共(子)属性(尽管表在“_id”字段上有不同的前缀,但数据域在每种情况下都是相同的)。在没有任何进一步信息的情况下,这些表不应被设计为单独的表,而应使用一个带有“type”属性的表,以及详细说明任何非公共属性的单独表。事实上,如果“posts”表中包含的所有内容都是包含数据的表的id和标识符,那么此时它就变得多余了—您应该有1个表,而不是4个表

除其他问题外,您不会遇到上述问题

如果您已经围绕此设计实现了一个系统,并且解决问题的成本太高,那么您可以通过以下方式应用解决方法:

SELECT *
FROM posts p
INNER JOIN (
   SELECT a.achievent_id AS common_id, .....
   FROM achievements a
   UNION
   SELECT g.game_id, .....
   FROM games g
   UNION
   SELECT e.event_id, ....
   FROM events e
 ) AS ilv
   ON p.id=ilv.id
在哪里。。。表示公共属性

但是除了没有提供表结构的详细信息之外,您也没有告诉我们查询将如何过滤——我怀疑您是否希望每次运行查询时都检索整个数据集。如何实现过滤将对性能产生很大影响

如果通过posts表上的筛选(即使用您没有告诉我们的某些属性),行数减少最多,则选择