【问题标题】:I want a better way of writing SQL that gets all comments from comments table, belonging to a particular article in articles table我想要一种更好的编写 SQL 的方法,它从评论表中获取所有评论,属于文章表中的特定文章
【发布时间】:2019-11-14 14:15:03
【问题描述】:

我有一个带有 PK_articleid 的文章表,以及一个带有 FK_articleid 的 cmets 表,它引用了文章表。我希望能够获得属于特定文章的所有 cmets。见下表:

到目前为止,我能够通过 INNER JOIN 获得所需的列,但我想要一种访问 cmets 对象属性的方法,如下面的“我想要的”示例对象中所示。

const text = 'SELECT a.articleid, a.createdon, a.title, a.article, c.id, c.comment, c.authorid  
FROM articles a INNER JOIN comments c ON a.articleid = c.articleid';

    exports.getArticleAndComments = (request, response) => {

      pool.query(text, (error, res) => {
        if (error) {
          // throw error
          console.log(`not able to get connection ${error}`);
          response.status(400).json({
            status: 'error',
            error: error.stack,
          });
        }
        response.status(200).json({
          status: 'success',
          data: {
            id: res.rows[0].articleid,
            createdon: res.rows[0].createdon,
            title: res.rows[0].title,
            article: res.rows[0].article,
            comments: res.rows
          },
        });
      });
    };

我想要什么:

"data" : {
    "id" : Integer ,
    "createdOn" : DateTime ,
    "title" : String ,
    "article" : String ,
    "comments" : [
      {
        "commentId" : Integer ,
        "comment" : String ,
        "authorId" : Integer ,
      } ,
      {
        "commentId" : Integer ,
        "comment" : String ,
        "authorId" : Integer ,
      } ,
    ]
  }

我得到了什么:

{
  "status": "success",
  "data": {
    "id": 21,
    "createdon": "2019-11-13T19:41:51.613Z",
    "title": "The gods must be crazy",
    "article": "An article about crazy gods",
    "comments": [
      {
        "articleid": 21,
        "createdon": "2019-11-13T19:41:51.613Z",
        "title": "The gods must be crazy",
        "article": "An article about crazy gods",
        "commentId": 28,
        "comment": "The gods have always been crazy",
        "authorid": 106
      },
      {
        "articleid": 21,
        "createdon": "2019-11-13T19:41:51.613Z",
        "title": "The gods must be crazy",
        "article": "An article about crazy gods",
        "commentId": 27,
        "comment": "Unleash the dragon",
        "authorid": 106
      }
    ]
  }
}

【问题讨论】:

  • 嗨,Uwem,这看起来像 nodejs,这不是我的强项,但您可能想添加一些有关您正在使用的库和数据库的信息。越具体越容易得到一些答案。
  • 查询返回所有文章的 cmets,而不仅仅是单个文章。为什么要从comments数组的第一行提取文章信息?
  • 如果要获取特定文章的cmets,查询中需要WHERE a.articleid = ?
  • 那么你是说你得到的数据比你想要的多吗?我能看到的唯一区别是名称和列数。如果是这种情况,那么只需将您的查询更改为仅返回您想要的内容,并将您的代码更改为仅读取您想要的数据,并根据需要命名。
  • @Barmar 与 LEFT JOIN,查询返回所有文章的 cmets,直到我使用 INNER JOIN。如您所见,它并不可靠,因为我必须提取文章,而不提取,它会为每条评论返回相同的文章。也许 JOIN 在这里并不理想。

标签: javascript sql node.js postgresql


【解决方案1】:

不是最好的方法,但最接近您的代码(因此,更改较少)

const text = 'SELECT a.articleid, a.createdon, a.title, a.article, c.id, c.comment, c.authorid  
FROM articles a INNER JOIN comments c ON a.articleid = c.articleid
WHERE a.articleid = YOUR_ARTICLE_ID_HERE';

exports.getArticleAndComments = (request, response) => {

  pool.query(text, (error, res) => {
    if (error) {
      // throw error
      console.log(`not able to get connection ${error}`);
      response.status(400).json({
        status: 'error',
        error: error.stack,
      });
    }
    response.status(200).json({
      status: 'success',
      data: {
        id: res.rows[0].articleid,
        createdon: res.rows[0].createdon,
        title: res.rows[0].title,
        article: res.rows[0].article,
        comments: res.rows.map((row) => {return {
          commentId: row.commentId,
          comment: row.comment,
          authorId: row.authorId,
        }})
      },
    });
  });
};

您说您想要“属于特定文章”的信息,请替换查询末尾的文章 ID (YOUR_ARTICLE_ID_HERE)。

【讨论】:

  • 这对我很有效。虽然有点 hacky,但如果我不能在接下来的一个小时内提出更好的查询语句,我会接受它。谢谢。
  • 酷,很高兴知道它有效。更好的方法是有两个查询:一个用于文章,一个用于 cmets,因此您不必在响应中拆分结果。这需要更多的工作来处理响应状态,但它会更加清晰。
【解决方案2】:

据我了解,您需要获取表 属性 而不是存储的数据。 在 postgres 中,获取表属性(列名和数据类型)的方法是按照那里的文档 https://www.postgresql.org/docs/current/infoschema-columns.html

查询信息模式

【讨论】:

  • 我认为他想要的输出中的数据类型只是占位符,他实际上想要数据。
猜你喜欢
  • 2011-08-03
  • 1970-01-01
  • 2017-04-10
  • 1970-01-01
  • 2021-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多