我应该将常见的SQL查询或CTE分开并放入一个变量中吗?

huangapple go评论76阅读模式
英文:

Should I separate common SQL query or CTE and put it in an variable?

问题

我有一些SQL查询,其中一些部分是相同的。用于获取有关房屋数据的CTE在这两个查询中看起来很相似。

const GetUserListSQL = `
  WITH "HouseData" AS (
    SELECT
      "UserId",
      json_object_agg(
        "Id",
        (SELECT x FROM (SELECT
          "Price",
          "Area",
          "Address"
        ) x)
      ) AS "HouseMap"
    FROM "Houses"
    GROUP BY "UserId"
  )
  SELECT
    "Id",
    "Name",
  FROM "Users"
  LEFT JOIN "HouseData" ON "Users"."Id" = "HouseData"."UserId"
`


const GetUserSQL = `
  WITH "HouseData" AS (
    SELECT
      json_object_agg(
        "Id",
        (SELECT x FROM (SELECT
          "Price",
          "Area",
          "Address"
        ) x)
      ) AS "HouseMap"
    FROM "Houses"
    WHERE "UserId" = $1
  )
  SELECT
    "Id",
    "Name",
  FROM "Users"
  LEFT JOIN "HouseData" ON TRUE
  WHERE "Users"."Id" = $1
`

我应该将获取房屋数据或用户字段的CTE作为单独的常量吗?这样做会增加可重用性(只需在一个地方添加字段)吗?这样做会降低可读性(看起来有点奇怪)?有人建议我像下面这样编写这些SQL:

const HouseDataCTE = `
  SELECT
    "UserId",
    json_object_agg(
      "Id",
      (SELECT x FROM (SELECT
        "Price" 
        "Area",
        "Address"
      ) x)
    ) AS "HouseMap"
  FROM "Houses"
`

const UserCommonSQL = `
  SELECT
    "Id",
    "Name"
  FROM "Users"
`

const GetUserListSQL = `
  WITH "HouseData" AS (
    ` + HouseDataCTE + `
    GROUP BY "UserId"
  )
  ` + UserCommonSQL + `
  LEFT JOIN "HouseData" ON "Users"."Id" = "HouseData"."UserId"
`

const GetUserSQL = `
  WITH "HouseData" AS (
    ` + HouseDataCTE + `
    WHERE "UserId" = $1
  )
  ` + UserCommonSQL + `
  LEFT JOIN "HouseData" ON TRUE
  WHERE "Users"."Id" = $1
`

如果我这样写,我觉得我必须来回跳转来检查SQL(查询不是放在一起的),在我看来有点烦人。对于这种情况,是否有任何约定或最佳实践?

编辑:上面的SQL查询是我正在使用的实际长SQL查询的缩写版本。更长的版本有来自不同表的4-5个CTE和关于"Users"的公共字段约20列。在这种情况下应该怎么办?

英文:

I have some sql queries that have some common parts in them. The CTE used to get the data about houses look similar in both queries.

const GetUserListSQL = `
  WITH "HouseData" AS (
    SELECT
      "UserId",
      json_object_agg(
        "Id",
        (SELECT x FROM (SELECT
          "Price",
          "Area",
          "Address"
        ) x)
      ) AS "HouseMap"
    FROM "Houses"
    GROUP BY "UserId"
  )
  SELECT
    "Id",
    "Name",
  FROM "Users"
  LEFT JOIN "HouseData" ON "Users"."Id" = "HouseData"."UserId"
`


const GetUserSQL = `
  WITH "HouseData" AS (
    SELECT
      json_object_agg(
        "Id",
        (SELECT x FROM (SELECT
          "Price",
          "Area",
          "Address"
        ) x)
      ) AS "HouseMap"
    FROM "Houses"
    WHERE "UserId" = $1
  )
  SELECT
    "Id",
    "Name",
  FROM "Users"
  LEFT JOIN "HouseData" ON TRUE
  WHERE "Users"."Id" = $1
`

Should I make the CTE to get house data or user fields a separate const? Will it increase reusability (like you only need to add fields in one place)? Will it reduce readability (it looks kind of weird somehow). Someone suggested that I wrote those SQL like below:

const HouseDataCTE = `
  SELECT
    "UserId",
    json_object_agg(
      "Id",
      (SELECT x FROM (SELECT
        "Price" 
        "Area",
        "Address"
      ) x)
    ) AS "HouseMap"
  FROM "Houses"
`

const UserCommonSQL = `
  SELECT
    "Id",
    "Name"
  FROM "Users"
`

const GetUserListSQL = `
  WITH "HouseData" AS (
    ` + HouseDataCTE + `
    GROUP BY "UserId"
  )
  ` + UserCommonSQL + `
  LEFT JOIN "HouseData" ON "Users"."Id" = "HouseData"."UserId"
`

const GetUserSQL = `
  WITH "HouseData" AS (
    ` + HouseDataCTE + `
    WHERE "UserId" = $1
  )
  ` + UserCommonSQL + `
  LEFT JOIN "HouseData" ON TRUE
  WHERE "Users"."Id" = $1
`

If I write it like that I feel like I have to jump back and forth to inspect the SQL (the queries are not placed close together), which is kind of annoying in my opinion. Are there any convention or best practices for these kinds of situation ?

EDIT: The sql queries above are shorter version of an actual long SQL queries I'm using. The longer version has 4-5 CTEs from different tables and the common fields for "Users" are about 20 columns. What should be done in that situation then?

答案1

得分: 1

根据我的经验,通常在每个存储过程中,公共表达式(CTE)会变得混乱。在你的使用情况下,是否可以利用一个基于CTE的视图?这样可以简化你的文档和代码维护工作。

英文:

in my experience the CTEs tended to get jumbled in each SP. Is it possible to leverage a view on the CTE instead n your use cases? That would clean up your documentation and code maintenance.

huangapple
  • 本文由 发表于 2017年1月17日 23:00:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/41700380.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定