You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL与Go中如何用CASE WHEN匹配二维数组实现产品分类加分?

解决方案:PostgreSQL + Go 实现分类匹配加权排序

方法1:使用jsonb类型(推荐)

这种方式适配Go的JSON处理习惯,PostgreSQL对jsonb的支持也非常成熟,写法简洁且性能稳定。

SQL语句

SELECT 
  products.*,
  -- 匹配不到时默认返回0,转成int类型
  COALESCE(($1::jsonb) ->> CAST(products.category AS text), '0')::int AS add_score
FROM products;

Go调用示例

import (
  "database/sql"
  "encoding/json"
  _ "github.com/lib/pq"
)

// 定义分类-权重映射
type CategoryScore map[int]int

func main() {
  db, err := sql.Open("postgres", "your_dsn_here")
  if err != nil {
    // 错误处理
  }
  defer db.Close()

  // 构造权重规则
  scoreRule := CategoryScore{1: 100, 3: 50, 4: 120}
  jsonRule, err := json.Marshal(scoreRule)
  if err != nil {
    // 错误处理
  }

  // 执行查询
  rows, err := db.Query(`
    SELECT id, category, COALESCE(($1::jsonb)->>CAST(category AS text), '0')::int AS add_score
    FROM products
  `, string(jsonRule))
  if err != nil {
    // 错误处理
  }
  defer rows.Close()

  // 处理查询结果
  for rows.Next() {
    var id, category, addScore int
    if err := rows.Scan(&id, &category, &addScore); err != nil {
      // 错误处理
    }
    // 业务逻辑处理
  }
}

方法2:使用PostgreSQL二维数组 + unnest

如果必须传入二维数组格式(如[[1,100],[3,50],[4,120]]),可以通过unnest将数组拆分为临时表,再通过左连接匹配权重。

SQL语句

WITH category_scores AS (
  SELECT 
    -- 拆分二维数组,取子数组的第一个元素作为分类ID
    (unnest($1::int[][]))[1] AS category,
    -- 取子数组的第二个元素作为权重值
    (unnest($1::int[][]))[2] AS score
)
SELECT 
  p.*,
  COALESCE(cs.score, 0) AS add_score
FROM products p
LEFT JOIN category_scores cs ON p.category = cs.category;

Go调用示例

import (
  "database/sql"
  _ "github.com/lib/pq"
)

func main() {
  db, err := sql.Open("postgres", "your_dsn_here")
  if err != nil {
    // 错误处理
  }
  defer db.Close()

  // 构造二维数组规则
  scoreRule := [][]int{{1, 100}, {3, 50}, {4, 120}}

  // 执行查询
  rows, err := db.Query(`
    WITH category_scores AS (
      SELECT 
        (unnest($1::int[][]))[1] AS category,
        (unnest($1::int[][]))[2] AS score
    )
    SELECT id, category, COALESCE(cs.score, 0) AS add_score
    FROM products p
    LEFT JOIN category_scores cs ON p.category = cs.category
  `, scoreRule)
  if err != nil {
    // 错误处理
  }
  defer rows.Close()

  // 处理查询结果
  // ...
}

方法3:动态生成CASE表达式(适合规则较少场景)

如果分类权重规则数量不多,可以在Go中动态拼接CASE语句,注意必须使用参数化查询避免SQL注入。

Go实现示例

import (
  "database/sql"
  "fmt"
  "strings"
  _ "github.com/lib/pq"
)

type CategoryScore map[int]int

func main() {
  db, err := sql.Open("postgres", "your_dsn_here")
  if err != nil {
    // 错误处理
  }
  defer db.Close()

  scoreRule := CategoryScore{1: 100, 3: 50, 4: 120}
  var caseClauses []string
  var args []interface{}
  argIndex := 1

  // 动态生成WHEN子句
  for cat, score := range scoreRule {
    caseClauses = append(caseClauses, fmt.Sprintf("WHEN category = $%d THEN $%d", argIndex, argIndex+1))
    args = append(args, cat, score)
    argIndex += 2
  }

  // 拼接完整CASE表达式
  caseExpr := strings.Join(caseClauses, " ")
  if caseExpr == "" {
    caseExpr = "ELSE 0"
  } else {
    caseExpr += " ELSE 0"
  }

  // 构造查询语句
  query := fmt.Sprintf(`
    SELECT id, category, CASE %s END AS add_score
    FROM products
  `, caseExpr)

  // 执行参数化查询
  rows, err := db.Query(query, args...)
  if err != nil {
    // 错误处理
  }
  defer rows.Close()

  // 处理查询结果
  // ...
}

内容的提问来源于stack exchange,提问作者JackPhillips

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 16:22:59