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