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

时间:2017-01-17 15:00:41

标签: sql go

我有一些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将房屋数据或用户字段作为单独的const吗?它会增加可重用性(就像你只需要在一个地方添加字段)?它是否会降低可读性(某种程度上看起来很奇怪)。有人建议我写下这些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以及"用户"大约20列。那种情况应该怎么做呢?

1 个答案:

答案 0 :(得分:1)

根据我的经验,CTE往往会在每个SP中混乱。是否可以利用CTE上的视图来代替您的用例?这样可以清理文档和代码维护。