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

如何基于列中字符串位置匹配,查询特定产品试用客户?

基于逗号分隔字符串筛选试用客户的SQL实现

问题场景

现有一个聚合客户数据的视图,结构及数据如下:

+----------+----------+-----------------------+
| customer | products | products_trial_status |
+----------+----------+-----------------------+
|   234253 | A,B,C    | false,true,false      |
|   923403 | A,C      | true,true             |
|   123483 | B        | true                  |
|   239874 | B,C      | false,false           |
+----------+----------+-----------------------+

需求是编写查询语句,返回使用特定产品且处于试用状态的客户列表。例如查询产品B的试用客户,预期结果为:

+----------+
| customer |
+----------+
|   234253 | 
|   123483 |
+----------+

已知核心思路是匹配目标产品在products列中的位置,再验证products_trial_status列对应位置的值为true,且无法修改现有字符串存储格式,必须基于当前结构解决。

解决方案

不同数据库的字符串处理函数存在差异,以下是主流数据库的实现方式:

1. MySQL/MariaDB 实现

利用FIND_IN_SET获取产品位置,结合SUBSTRING_INDEX提取对应试用状态:

SELECT customer
FROM your_view_name
WHERE FIND_IN_SET('B', products) > 0
  AND SUBSTRING_INDEX(
        SUBSTRING_INDEX(products_trial_status, ',', FIND_IN_SET('B', products)),
        ',',
        -1
      ) = 'true';

逻辑说明:

  • FIND_IN_SET('B', products)返回产品B在逗号分隔字符串中的位置(从1开始计数,不存在则返回0)
  • 内层SUBSTRING_INDEX截取到目标位置前的所有内容,外层SUBSTRING_INDEX提取最后一个元素,即对应位置的试用状态

2. PostgreSQL 实现

通过string_to_array将字符串转为数组,利用数组索引匹配对应状态:

SELECT customer
FROM your_view_name
WHERE 'B' = ANY(string_to_array(products, ','))
  AND (string_to_array(products_trial_status, ','))[array_position(string_to_array(products, ','), 'B')] = 'true';

逻辑说明:

  • string_to_array将逗号分隔字符串转为数组,'B' = ANY(...)判断产品B是否存在
  • array_position获取产品B在数组中的位置,再用该索引提取试用状态数组对应位置的值进行判断

3. SQL Server 实现

提供两种实现方式,其中拆分关联的方式更清晰:

方式一:字符串直接匹配

SELECT customer
FROM your_view_name
WHERE CHARINDEX(',B,', ',' + products + ',') > 0
  AND SUBSTRING(
        ',' + products_trial_status + ',',
        CHARINDEX(',B,', ',' + products + ','),
        LEN(',true,')
      ) = ',true,';

逻辑说明:在字符串前后加逗号,避免产品B在开头/结尾的边界匹配问题,通过位置截取对应试用状态进行匹配

方式二:拆分后关联

WITH customer_products AS (
    SELECT 
        customer,
        value AS product,
        ROW_NUMBER() OVER (PARTITION BY customer ORDER BY (SELECT NULL)) AS rn
    FROM your_view_name
    CROSS APPLY STRING_SPLIT(products, ',')
),
customer_trial_status AS (
    SELECT 
        customer,
        value AS trial_status,
        ROW_NUMBER() OVER (PARTITION BY customer ORDER BY (SELECT NULL)) AS rn
    FROM your_view_name
    CROSS APPLY STRING_SPLIT(products_trial_status, ',')
)
SELECT cp.customer
FROM customer_products cp
JOIN customer_trial_status cts ON cp.customer = cts.customer AND cp.rn = cts.rn
WHERE cp.product = 'B' AND cts.trial_status = 'true';

逻辑说明:分别拆分产品和试用状态字符串,添加行号关联对应位置,再筛选目标产品和试用状态

内容的提问来源于stack exchange,提问作者أُكَاتِبُ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 18:40:26