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

求助:基于C#网站开发商品关联推荐功能的SQL查询实现

基于购物篮分析的商品推荐SQL实现

嘿,这个需求太适合项目初期快速落地了!不用复杂的机器学习模型,纯SQL就能搞定基于频繁关联的商品推荐,完全贴合你说的类似Stack Overflow「相关内容」的思路。

首先咱们得先明确基础的数据库表结构——假设你有一张记录订单商品关联的表OrderItems,结构大概是这样:

  • OrderId:订单唯一标识(比如GUID或者自增ID)
  • ProductName:商品名称(和你输入的查询字段对应)

核心SQL查询实现

我给你写两种方案:一种是按关联频率从高到低返回,另一种是筛选关联占比≥50%的商品,你可以按需选择。

方案1:返回关联最频繁的Top N商品

这个方案会统计所有和目标商品出现在同一订单里的其他商品,按出现次数排序,返回Top N(比如Top 5):

WITH TargetOrders AS (
    -- 先找出所有包含目标商品的订单ID
    SELECT DISTINCT OrderId
    FROM OrderItems
    WHERE ProductName = @TargetProduct -- 这里用参数化,避免SQL注入
)
SELECT 
    oi.ProductName AS RecommendedProduct,
    COUNT(DISTINCT oi.OrderId) AS CoOccurrenceCount, -- 统计共同出现的订单数
    ROUND(COUNT(DISTINCT oi.OrderId) * 100.0 / (SELECT COUNT(*) FROM TargetOrders), 2) AS CoOccurrencePercentage
FROM OrderItems oi
JOIN TargetOrders TOs ON oi.OrderId = TOs.OrderId
WHERE oi.ProductName != @TargetProduct -- 排除目标商品本身
GROUP BY oi.ProductName
ORDER BY CoOccurrenceCount DESC
LIMIT 5; -- 可以调整返回的数量,比如Top 10

方案2:返回关联占比≥50%的商品

如果要直接筛选出和目标商品在≥50%的共同订单里出现的商品,只需要在上面的基础上加个HAVING条件:

WITH TargetOrders AS (
    SELECT DISTINCT OrderId
    FROM OrderItems
    WHERE ProductName = @TargetProduct
)
SELECT 
    oi.ProductName AS RecommendedProduct,
    COUNT(DISTINCT oi.OrderId) AS CoOccurrenceCount,
    ROUND(COUNT(DISTINCT oi.OrderId) * 100.0 / (SELECT COUNT(*) FROM TargetOrders), 2) AS CoOccurrencePercentage
FROM OrderItems oi
JOIN TargetOrders TOs ON oi.OrderId = TOs.OrderId
WHERE oi.ProductName != @TargetProduct
GROUP BY oi.ProductName
HAVING ROUND(COUNT(DISTINCT oi.OrderId) * 100.0 / (SELECT COUNT(*) FROM TargetOrders), 2) >= 50.0
ORDER BY CoOccurrencePercentage DESC;

关键细节说明

  • 参数化查询:一定要用@TargetProduct这种参数,不要直接拼接字符串,防止SQL注入——在C#里调用的时候,用SqlParameter或者EF Core的参数化查询就行。
  • 去重处理:用DISTINCT OrderId是因为同一个订单里多次买同一个商品,应该只算一次关联,避免重复统计。
  • 大小写问题:如果你的商品名称大小写不敏感(比如'ABC'和'abc'算同一个),可以把WHERE ProductName = @TargetProduct改成WHERE LOWER(ProductName) = LOWER(@TargetProduct)。

C#调用示例(用ADO.NET)

给你个简单的C#调用示例,确保参数化:

public List<string> GetRecommendedProducts(string targetProduct)
{
    var recommendedProducts = new List<string>();
    string connectionString = "你的数据库连接字符串";
    string sql = @"
        WITH TargetOrders AS (
            SELECT DISTINCT OrderId
            FROM OrderItems
            WHERE ProductName = @TargetProduct
        )
        SELECT oi.ProductName
        FROM OrderItems oi
        JOIN TargetOrders TOs ON oi.OrderId = TOs.OrderId
        WHERE oi.ProductName != @TargetProduct
        GROUP BY oi.ProductName
        ORDER BY COUNT(DISTINCT oi.OrderId) DESC
        LIMIT 5;";

    using (SqlConnection conn = new SqlConnection(connectionString))
    {
        conn.Open();
        using (SqlCommand cmd = new SqlCommand(sql, conn))
        {
            cmd.Parameters.AddWithValue("@TargetProduct", targetProduct);
            using (SqlDataReader reader = cmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    recommendedProducts.Add(reader["ProductName"].ToString());
                }
            }
        }
    }
    return recommendedProducts;
}

后续优化建议

如果以后数据量变大了,纯SQL可能会有点慢,你可以考虑:

  • 预计算关联商品的统计结果,定时更新到一张专门的推荐表(比如ProductRecommendations),查询的时候直接读这张表。
  • 引入更精细的维度,比如按用户分类、时间段来计算关联,推荐会更精准。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:13:41