简体   繁体   English

MySQL查询从另一个表中检索相关数据

[英]MySQL query to retrieve related data from another table

I'm not too experienced with SQL queries (most times I used query builder from frameworks, like CodeIgniter and Laravel).我对 SQL 查询不太熟悉(大多数时候我使用框架中的查询构建器,如 CodeIgniter 和 Laravel)。 Now, I need to retrieve data from a relational DB which have two tables: one for entity entries and other for complemental data of entities.现在,我需要从具有两个表的关系数据库中检索数据:一个用于实体条目,另一个用于实体的补充数据。 For example, see below:例如,见下文:

tbl_posts tbl_posts

id ID name姓名 slug蛞蝓
1 1 Lorem ipsum Lorem ipsum lorem-ipsum lorem-ipsum
2 2 Testing post测试帖 testing-post测试站
3 3 Hello world你好世界 hello-world你好世界

tbl_posts_meta tbl_posts_meta

id ID post_id post_id key钥匙 value价值
1 1 1 1 first_name John约翰
2 2 1 1 last_name Doe能源部
3 3 1 1 rating评分 5 5
4 4 2 2 parent父母 1 1
5 5 2 2 rating评分 3 3
6 6 3 3 rating评分 4 4

In this example, I need to retrieve an array of objects in this format:在这个例子中,我需要以这种格式检索一个对象数组:

[
  {
    id: 1,
    name: "Lorem ipsum",
    slug: "lorem-ipsum",
    data: {
      first_name: "John",
      last_name: "Doe",
      rating: 5,
    }
  },
  {
    id: 2,
    name: "Testing post",
    slug: "testing-post",
    data: {
      parent: 1,
      rating: 3,
    }
  },
  {
    id: 3,
    name: "Hello World",
    slug: "hello-world",
    data: {
      rating: 4,
    }
  },
]

I've tried using subquery to handle this, but I'm reveiving Cardinality violation: 1241 Operand should contain 1 column(s) error.我已经尝试使用子查询来处理这个问题,但我正在恢复Cardinality violation: 1241 Operand should contain 1 column(s)错误。 My query looks like this:我的查询如下所示:

SELECT *,(SELECT * FROM tbl_posts_meta WHERE "post_id" = "tbl_posts"."id") as data FROM tbl_posts;

I've already tried using JOIN, but the result looks more away from expected (I have one "key" property and one "value" property in result, containing the last found entry in tbl_posts_meta).我已经尝试过使用 JOIN,但结果看起来与预期相差甚远(结果中有一个“键”属性和一个“值”属性,包含 tbl_posts_meta 中最后找到的条目)。

SELECT * FROM tbl_posts INNER JOIN tbl_posts_meta ON tbl_posts_meta.post_id = tbl_posts.id;

Is there someway I can retrieve desired results with one query?有没有办法通过一个查询来检索所需的结果? I don't want to do this by applogic (like first retrieving data from tbl_posts and appending another query on "data" property, that returns all data from tbl_posts_meta), since this way may cause database overload.我不想通过 applogic 执行此操作(例如首先从 tbl_posts 检索数据并在“data”属性上附加另一个查询,该查询返回来自 tbl_posts_meta 的所有数据),因为这种方式可能会导致数据库过载。

Thanks!谢谢!

The code is not shown right in the comment so here it is for you to check, sorry I can't contribute more to the theoretical debate:该代码未在评论中正确显示,因此您可以在这里检查,抱歉,我无法为理论辩论做出更多贡献:

select 
tp.id,
tp.name,
tp.slug,
(select group_concat(`key`, "=",value separator ';' ) from tbl_posts_meta where post_id= tp.id )as datas
from tbl_posts tp

You can follow these simple steps to get to your needed json:您可以按照以下简单步骤获取所需的 json:

  • join the two tables to have centralized data连接两个表以获得集中的数据
  • generate a tbl_posts_meta JSON-like string by aggregating on your columns of interest ( tbl_posts.id , tbl_posts.name , tbl_posts.slug ) using a GROUP_CONCAT aggregation function.通过使用GROUP_CONCAT聚合函数聚合您感兴趣的列( tbl_posts.idtbl_posts.nametbl_posts.slug )来生成类似tbl_posts_meta的 JSON 字符串。 Since your keys can either be integers or strings, you need to do a quick check using the CAST(<col> AS UNSIGNED) , which will return 0 if the string is not a number.由于您的键可以是整数或字符串,因此您需要使用CAST(<col> AS UNSIGNED)进行快速检查,如果字符串不是数字,它将返回 0。
  • use the JSON_OBJECT function to transform each row into a JSON使用JSON_OBJECT函数将每一行转换为 JSON
  • use the JSON_ARRAYAGG function to merge all jsons into a single json.使用JSON_ARRAYAGG函数将所有 json 合并为一个 json。
WITH cte AS(
    SELECT p.id,
           p.name, 
           p.slug,
           CONCAT('{',
                  GROUP_CONCAT(
                      CONCAT('"', 
                             m.key_, 
                             '": ', 
                             IF(CAST(m.value_ AS UNSIGNED)=0, 
                                CONCAT('"', m.value_, '"'),
                                CAST(m.value_ AS UNSIGNED))  ) 
                      ORDER BY m.id                             ),
                  '}') AS data_
    FROM       tbl_posts      p
    INNER JOIN tbl_posts_meta m
            ON p.id = m.post_id
    GROUP BY p.id,
             p.name, 
             p.slug
)
SELECT JSON_ARRAYAGG(
           JSON_OBJECT("id",   id, 
                       "name", name, 
                       "slug", slug, 
                       "data", CAST(data_ AS JSON))) 
FROM cte

Check the demo here .此处查看演示。

After some research, testing and reading the queries you posted here, I've finally reached the result I needed.经过一些研究、测试和阅读您在此处发布的查询,我终于达到了我需要的结果。 The final query is structured this way:最终查询的结构如下:

SELECT *, (
  SELECT JSON_ARRAYAGG(
    JSON_OBJECT(
      key, value
    )
  ) FROM tbl_posts_meta WHERE post_id = post.id
) AS data
FROM tbl_posts;

Translating it to Laravel's Eloquent query builder, and using PHP's serialize/unserialize functions, the end result looks like this:将其转换为 Laravel 的 Eloquent 查询构建器,并使用 PHP 的序列化/反序列化函数,最终结果如下所示:

$posts = Post::query()
          ->select("*")
          ->selectRaw('(SELECT JSON_ARRAYAGG(JSON_OBJECT(key, value)) FROM tbl_posts_meta WHERE post_id = posts.id) as data');

return $posts->get()->map(function($post){
  $meta = [];
  foreach($post->data as $dataItem){
    foreach($dataItem as $key => $value){
      $meta[$key] = unserialize($value);
    }
  }
  $post->data = $meta;
  return $post;
});

Thank you for your support and attention!感谢您的支持和关注! :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从另一个表中检索所有数据以及相关数据-mysql,PHP - Retrieve all datas along with related data from another table - mysql, PHP 从一个表中检索数据并在mysql中的另一个表中插入/更新 - Retrieve data from one table and insert/update in another table in mysql 在正在从另一个表中恢复其他数据的循环中,从相关表中检索数据 - retrieve data from a related table in a loop that is recovering other data from another table mysql查询从不同的表中获取相关数据以获得建议的连接 - mysql query for getting related data from different table for suggested connections php \\ mysql在一个查询中从两个不相关的表中删除数据 - php\mysql delete data from two not related table in one query 从Laravel中的多个相关表中检索数据 - Retrieve data from multiple related table in laravel 从一个MySQL表中检索数据并在另一个MySQL表中使用 - Retrieve data from one MySQL table and use it in another one MYSQL查询以从关系表中检索数据并过滤出重复项 - MYSQL query to retrieve data from a relational table and filter out duplicates 如何从 MySQL 中的另一个表中检索数据,同时从第一个表的列中获取数据? - How to retrieve data from another table in MySQL while having a data from column from the first table? 使用join的Eloquent查询来检索数据透视表和相关数据 - Eloquent query using join to retrieve pivot table and related data
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM