【问题标题】:Raw SQL queries in a REST ApiREST Api 中的原始 SQL 查询
【发布时间】:2014-12-16 19:27:12
【问题描述】:

假设我有这两张桌子:

帖子

 id | user_id | title | slug | content | views
----+---------+-------+------+---------+-------

用户

 id | username | email | hash | role | auth 
----+----------+-------+------+------+------

对于这两个表,我想做一个SELECT * FROM posts ... 查询,最终得到如下响应:

{[
  {
    "id": "1",
    "user_id": "2",
    "title": "Foo",
    "slug": "foo",
    "content": "bar",
    "views": "0",
    "user": {
      "id": "2",
      "username": "john",
      "email": "john@smith.com",
      "hash": "aeigh*£HAEGhoiaehg",
      "role": "admin",
      "auth": "aeg89hiae9g8hA*H£GA(*EHG"
    }
  }
]}

我对 SQL 很陌生,在使用 ORM 时,这样的模式似乎很常见,所以我想知道我必须执行哪些步骤才能使用原始 SQL 获得这样的结果。

有什么想法吗?

【问题讨论】:

    标签: sql postgresql relational-database


    【解决方案1】:

    在 postgresql 9.2 或更高版本中,您可以使用 row_to_json 函数:

    select row_to_json(posts) 
    from 
      posts....;
    

    Read more

    您的查询可能类似于:

    select row_to_json(row)
    from (
        select p.*, urd AS user
        from posts p
        inner join (
            select ur.*
            from users ur
        ) urd(id,username,email,hash,role,auth) on urd.id = p.user_id 
    ) row;
    

    直接的 sql 不需要那么复杂:

    select
      p.*, u.*
    from
      posts p
      inner join users u on p.user_id = u.id
    

    【讨论】:

    • 看起来很有趣。虽然,这将如何帮助我加入数据?我可能应该更具体地了解我的需求,但我更关心这一点而不是转换为 JSON。
    • @daryl 不确定我的语法是否完美,但可以加入数据以获得您需要的内容。那里的递归urd 方法是从stackoverflow.com/a/13227451/2589202 拼凑而成的
    • 嘿,只是想知道,是否可以在不将其返回为 JSON 的情况下执行此操作? (我稍后会转换它)
    • @daryl json 是一种分层格式,而 sql 不是。因此,p 的数据将被复制,但会为您提供唯一的 u。希望这是有道理的。
    • 是的,与此类似,知道如何在代码中管理该响应以便提取用户列吗?
    【解决方案2】:

    我必须执行哪些步骤才能使用原始 SQL 获得这样的结果。

    row_to_json() 有第二个参数来漂亮地打印外层。 The manual:

    如果 pretty_bool 为真,将在 1 级元素之间添加换行符。

    使用子查询将用户添加到行:

    SELECT row_to_json(combi, true) AS pretty_json
    FROM  (
       SELECT p.*, u AS user  --  whole users row
       FROM   posts p
       JOIN   users u ON u.id = p.user_id
       WHERE  p.id = 1
       ) combi;
    

    您只需要一个子查询级别。

    或者在 Postgres 9.4 或更高版本中使用 jsonb_pretty() 来漂亮地打印所有级别:

    SELECT jsonb_pretty(to_jsonb(combi)) AS pretty_jsonb
    FROM  (
       SELECT p.*, u AS user
       FROM   posts p
       JOIN   users u ON u.id = p.user_id
       WHERE  p.id = 1
       ) combi;
    

    键(以前的列名)现在按字母顺序排列,这就是它们在jsonb 中的存储方式。

    dbfiddle here
    OLD sqlfiddle - 转换为文本 (::text) 进行显示;不显示换行

    【讨论】:

      【解决方案3】:

      或者,您可以使用薄的中间层 - restSQL。它是一个开源的、超轻量级的持久层,对 PostgreSQL 提供开箱即用的支持。它已使用 9.3 进行了测试,但 9.2 可能不是问题。

      您可以使用 docker 映像在大约 10 分钟内完成部署。

      【讨论】:

        猜你喜欢
        • 2016-08-31
        • 2013-04-17
        • 2021-07-27
        • 2015-11-21
        • 2012-03-16
        • 2014-04-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多