使用 SQL 进行队列分析

你推出了一款新应用,用户每天都在注册。但这里有一个价值百万的问题:他们会回来吗?

队列分析概览:展示不同队列(JAN 2023, MAB 2023, MAR 2023, APR 2023, MAY 2023)在不同月份的留存率变化

单一指标如"总活跃用户数"无法告诉你完整的故事。你需要知道:1月注册的用户在3月还活跃吗?他们比2月注册的用户更活跃吗?

这就是队列分析(Cohort Analysis)的用武之地------产品分析中最强大的技术之一。最棒的是?你可以完全用 SQL 来实现它。

什么是队列分析?

队列(Cohort)是一组在特定时间段内共享共同特征的用户。例如:

  • 所有在 2024年1月 注册的用户
  • 所有在 黑色星期五 首次购买的用户

队列分析 跟踪这些群体随时间的行为变化。最常见的用例是留存分析(Retention Analysis):衡量用户在首次互动后回归的百分比。

为什么队列分析很重要?

想象你正在运营一个 SaaS 产品。你注意到:

  • 1月队列:60% 的用户在3个月后仍然活跃
  • 2月队列:只有30% 的用户在3个月后仍然活跃

这告诉你1月和2月之间发生了一些变化。也许你发布了一个有 bug 的功能,或者你的入门流程出了问题。没有队列分析,你永远不会发现这一点。

队列分析的价值:

队列分析帮助你回答关键的业务问题,包括产品留存率评估、功能变更影响分析、用户生命周期价值预测以及流失预警和干预。通过对比不同时期的队列表现,你可以量化产品改进的效果,识别用户流失的关键节点,并制定更精准的用户运营策略。

数据模型

让我们使用一个简单的电商示例。我们有一个 user_activity 表,跟踪用户访问网站的时间:

示例数据:user_activity 表

user_id activity_date
1 2024-01-05
1 2024-01-12
1 2024-02-03
2 2024-01-10
2 2024-01-15
3 2024-01-20
3 2024-02-10
3 2024-03-05
4 2024-02-05
4 2024-02-15

我们想回答:1月加入的用户中有多少百分比在2月回来了?

步骤 1:识别队列

首先,我们需要确定每个用户的队列------他们首次活跃的月份。

sql 复制代码
SELECT 
  user_id,
  DATE_TRUNC('month', MIN(activity_date)) AS cohort_month
FROM user_activity
GROUP BY user_id;

查询结果:

user_id cohort_month
1 2024-01-01
2 2024-01-01
3 2024-01-01
4 2024-02-01

结果解读 :用户 1、2、3 属于 2024年1月队列 ,用户 4 属于 2024年2月队列。

跨数据库语法:

数据库 月份截断语法
PostgreSQL DATE_TRUNC('month', activity_date)
MySQL DATE_FORMAT(activity_date, '%Y-%m-01')
SQL Server DATEFROMPARTS(YEAR(activity_date), MONTH(activity_date), 1)
SQLite DATE(activity_date, 'start of month')

步骤 2:计算活动周期

接下来,对于每次活动,我们计算自用户队列月份以来已经过去了多少个月。这被称为周期数(Period Number)。

sql 复制代码
WITH cohorts AS (
  SELECT 
    user_id,
    DATE_TRUNC('month', MIN(activity_date)) AS cohort_month
  FROM user_activity
  GROUP BY user_id
)
SELECT 
  ua.user_id,
  c.cohort_month,
  DATE_TRUNC('month', ua.activity_date) AS activity_month,
  (EXTRACT(YEAR FROM ua.activity_date) - EXTRACT(YEAR FROM c.cohort_month)) * 12 
    + (EXTRACT(MONTH FROM ua.activity_date) - EXTRACT(MONTH FROM c.cohort_month)) AS period_number
FROM user_activity ua
JOIN cohorts c ON ua.user_id = c.user_id;

查询结果:

user_id cohort_month activity_month period_number
1 2024-01-01 2024-01-01 0
1 2024-01-01 2024-01-01 0
1 2024-01-01 2024-02-01 1
2 2024-01-01 2024-01-01 0
2 2024-01-01 2024-01-01 0
3 2024-01-01 2024-01-01 0
3 2024-01-01 2024-02-01 1
3 2024-01-01 2024-03-01 2
4 2024-02-01 2024-02-01 0
4 2024-02-01 2024-02-01 0

周期数说明:

  • Period 0 = 队列月份(用户首次活跃的月份)
  • Period 1 = 1个月后
  • Period 2 = 2个月后
  • 以此类推

工作原理:

  1. CTE cohorts:为每个用户计算队列月份(首次活跃月份)
  2. JOIN:将每次活动与用户的队列月份关联
  3. period_number 计算:使用年份和月份的差值计算周期数

步骤 3:构建留存矩阵

现在我们统计每个队列在每个周期有多少用户活跃。

sql 复制代码
-- 完整的队列分析查询
WITH cohorts AS (
  SELECT 
    user_id,
    DATE(MIN(activity_date), 'start of month') AS cohort_month
  FROM user_activity
  GROUP BY user_id
),
user_periods AS (
  SELECT 
    ua.user_id,
    c.cohort_month,
    DATE(ua.activity_date, 'start of month') AS activity_month,
    (CAST(strftime('%Y', ua.activity_date) AS INTEGER) - CAST(strftime('%Y', c.cohort_month) AS INTEGER)) * 12 
      + (CAST(strftime('%m', ua.activity_date) AS INTEGER) - CAST(strftime('%m', c.cohort_month) AS INTEGER)) AS period_number
  FROM user_activity ua
  JOIN cohorts c ON ua.user_id = c.user_id
)
SELECT 
  cohort_month,
  period_number,
  COUNT(DISTINCT user_id) AS active_users
FROM user_periods
GROUP BY cohort_month, period_number
ORDER BY cohort_month, period_number;

查询结果:

cohort_month period_number active_users
2024-01-01 0 3
2024-01-01 1 2
2024-01-01 2 1
2024-02-01 0 1

结果解读:

  • 2024-01-01, Period 0: 3个用户(所有1月注册的用户在1月都活跃)
  • 2024-01-01, Period 1: 2个用户(3个1月注册用户中有2个在2月回来了)
  • 2024-01-01, Period 2: 1个用户(3个1月注册用户中有1个在3月回来了)
  • 2024-02-01, Period 0: 1个用户(2月注册的用户在2月活跃)

留存率计算公式:

复制代码
留存率 = (Period N 的活跃用户数) / (Period 0 的活跃用户数) × 100%

对于1月队列:

  • Month 1 留存率: 2/3 = 67%
  • Month 2 留存率: 1/3 = 33%

查询解析:

  1. cohorts CTE:识别每个用户的队列月份
  2. user_periods CTE:计算每次活动的周期数
  3. 最终查询:按队列月份和周期数分组,统计活跃用户数

可视化队列数据

留存热力图:使用颜色(绿色=高留存,红色=低留存)展示不同队列的留存率

在实践中,你会将这些数据导出到 Excel、Google Sheets 或 BI 平台来创建留存热力图:

队列 Month 0 Month 1 Month 2
2024年1月 100% 67% 33%
2024年2月 100% 100% 100%

颜色编码:

  • 绿色 = 高留存(80%+)
  • 黄色 = 中等留存(50-80%)
  • 红色 = 低留存(<50%)

热力图的价值:

热力图让你一眼就能看出哪些队列表现良好,哪些队列需要关注。例如,如果你看到某个队列的留存率突然下降,你可以立即调查那个时期发生了什么(产品变更、营销活动、外部事件等)。

高级:计算队列指标

一旦你有了队列结构,你可以计算其他指标:

每个队列的平均收入

sql 复制代码
SELECT 
  c.cohort_month,
  AVG(o.order_total) AS avg_revenue
FROM orders o
JOIN cohorts c ON o.user_id = c.user_id
GROUP BY c.cohort_month;

示例数据:orders 表

user_id order_total order_date
1 100.00 2024-01-10
1 50.00 2024-02-05
2 200.00 2024-01-15
3 75.00 2024-01-25
4 150.00 2024-02-10

查询结果:

cohort_month avg_revenue
2024-01-01 106.25
2024-02-01 150.00

业务洞察:2月队列的平均收入更高,可能是因为营销活动吸引了更高价值的用户。

流失率

sql 复制代码
-- 在 Period 0 活跃但在 Period 1 不活跃的用户
SELECT 
  cohort_month,
  COUNT(DISTINCT CASE WHEN period_number = 0 THEN user_id END) AS period_0_users,
  COUNT(DISTINCT CASE WHEN period_number = 1 THEN user_id END) AS period_1_users,
  1.0 - (COUNT(DISTINCT CASE WHEN period_number = 1 THEN user_id END) * 1.0 / 
         COUNT(DISTINCT CASE WHEN period_number = 0 THEN user_id END)) AS churn_rate
FROM user_periods
GROUP BY cohort_month;

查询结果:

cohort_month period_0_users period_1_users churn_rate
2024-01-01 3 2 0.33
2024-02-01 1 1 0.00

流失率解读:

  • 1月队列:33% 的用户在第一个月后流失
  • 2月队列:0% 的用户流失(所有用户都回来了)

流失率 vs 留存率:

  • 流失率 = 1 - 留存率
  • 流失率关注离开的用户,留存率关注留下的用户

用户生命周期价值(LTV)

sql 复制代码
SELECT 
  c.cohort_month,
  SUM(o.order_total) / COUNT(DISTINCT c.user_id) AS ltv
FROM cohorts c
LEFT JOIN orders o ON c.user_id = o.user_id
GROUP BY c.cohort_month;

查询结果:

cohort_month ltv
2024-01-01 141.67
2024-02-01 150.00

LTV 解读:每个1月队列用户平均贡献 141.67 的收入,而2月队列用户平均贡献 150.00。

最佳实践

1. 选择正确的队列窗口

月度队列很常见,但你也可以使用周度或日度队列,具体取决于产品的节奏。

队列窗口选择指南:

产品类型 推荐队列窗口 原因
快速迭代的移动应用 日度或周度 用户行为变化快,需要快速反馈
SaaS 产品 月度 用户订阅周期通常是月度
电商平台 月度或季度 购买周期较长
社交媒体 周度 用户互动频繁

2. 明确定义"活跃"

用户"活跃"的定义是什么?登录?购买?与内容互动?保持一致。

活跃定义示例:

产品类型 活跃定义
SaaS 产品 登录并使用核心功能
电商平台 浏览商品或购买
社交媒体 发布内容或互动(点赞、评论)
内容平台 观看视频或阅读文章

错误示例:

sql 复制代码
-- ❌ 不一致的活跃定义
SELECT * FROM user_activity WHERE login_count > 0  -- 有时用登录
SELECT * FROM user_activity WHERE purchase_count > 0  -- 有时用购买

正确示例:

sql 复制代码
-- ✅ 一致的活跃定义
SELECT * FROM user_activity WHERE engaged = TRUE  -- 统一的活跃标志

3. 使用 CTE 提高可读性

队列查询可能很复杂。用 CTE(Common Table Expressions)分步骤处理。

不推荐(一个巨大的嵌套查询):

sql 复制代码
-- ❌ 难以阅读和维护
SELECT cohort_month, period_number, COUNT(DISTINCT user_id)
FROM (
  SELECT ua.user_id, c.cohort_month, ...
  FROM user_activity ua
  JOIN (SELECT user_id, MIN(activity_date) AS cohort_month FROM user_activity GROUP BY user_id) c
  ON ua.user_id = c.user_id
) sub
GROUP BY cohort_month, period_number;

推荐(使用 CTE):

sql 复制代码
-- ✅ 清晰、易读、易维护
WITH cohorts AS (...),
     user_periods AS (...)
SELECT cohort_month, period_number, COUNT(DISTINCT user_id)
FROM user_periods
GROUP BY cohort_month, period_number;

4. 使用视图自动化

创建视图以便分析师轻松查询队列逻辑。

sql 复制代码
CREATE VIEW cohort_retention AS
WITH cohorts AS (
  SELECT user_id, DATE_TRUNC('month', MIN(activity_date)) AS cohort_month
  FROM user_activity
  GROUP BY user_id
),
user_periods AS (
  SELECT 
    ua.user_id,
    c.cohort_month,
    DATE_TRUNC('month', ua.activity_date) AS activity_month,
    (EXTRACT(YEAR FROM ua.activity_date) - EXTRACT(YEAR FROM c.cohort_month)) * 12 
      + (EXTRACT(MONTH FROM ua.activity_date) - EXTRACT(MONTH FROM c.cohort_month)) AS period_number
  FROM user_activity ua
  JOIN cohorts c ON ua.user_id = c.user_id
)
SELECT 
  cohort_month,
  period_number,
  COUNT(DISTINCT user_id) AS active_users
FROM user_periods
GROUP BY cohort_month, period_number;

使用视图:

sql 复制代码
-- 分析师可以轻松查询
SELECT * FROM cohort_retention WHERE cohort_month = '2024-01-01';

5. 处理数据质量问题

确保数据质量,避免重复记录和异常值。

sql 复制代码
-- 去重
WITH clean_activity AS (
  SELECT DISTINCT user_id, DATE(activity_date) AS activity_date
  FROM user_activity
  WHERE activity_date IS NOT NULL  -- 过滤 NULL 值
    AND user_id IS NOT NULL
)
SELECT * FROM clean_activity;

实际应用场景

1. SaaS 产品留存分析

场景:你运营一个项目管理工具,想知道不同月份注册的用户的留存情况。

查询:

sql 复制代码
WITH cohorts AS (
  SELECT user_id, DATE_TRUNC('month', MIN(signup_date)) AS cohort_month
  FROM users
  GROUP BY user_id
),
user_periods AS (
  SELECT 
    l.user_id,
    c.cohort_month,
    DATE_TRUNC('month', l.login_date) AS activity_month,
    (EXTRACT(YEAR FROM l.login_date) - EXTRACT(YEAR FROM c.cohort_month)) * 12 
      + (EXTRACT(MONTH FROM l.login_date) - EXTRACT(MONTH FROM c.cohort_month)) AS period_number
  FROM logins l
  JOIN cohorts c ON l.user_id = c.user_id
)
SELECT 
  cohort_month,
  period_number,
  COUNT(DISTINCT user_id) AS active_users
FROM user_periods
GROUP BY cohort_month, period_number
ORDER BY cohort_month, period_number;

业务洞察:如果你发现某个月的队列留存率特别低,可以调查那个月发生了什么(产品变更、营销活动、竞争对手动作等)。

2. 电商平台购买队列

场景:你想知道首次购买用户的复购率。

查询:

sql 复制代码
WITH cohorts AS (
  SELECT user_id, DATE_TRUNC('month', MIN(order_date)) AS cohort_month
  FROM orders
  GROUP BY user_id
),
user_periods AS (
  SELECT 
    o.user_id,
    c.cohort_month,
    DATE_TRUNC('month', o.order_date) AS activity_month,
    (EXTRACT(YEAR FROM o.order_date) - EXTRACT(YEAR FROM c.cohort_month)) * 12 
      + (EXTRACT(MONTH FROM o.order_date) - EXTRACT(MONTH FROM c.cohort_month)) AS period_number
  FROM orders o
  JOIN cohorts c ON o.user_id = c.user_id
)
SELECT 
  cohort_month,
  period_number,
  COUNT(DISTINCT user_id) AS repeat_buyers
FROM user_periods
GROUP BY cohort_month, period_number
ORDER BY cohort_month, period_number;

业务洞察:复购率是电商的关键指标。如果某个队列的复购率低,可能需要改进产品质量或客户服务。

3. 内容平台用户参与度

场景:你运营一个视频平台,想知道不同队列的用户观看频率。

查询:

sql 复制代码
WITH cohorts AS (
  SELECT user_id, DATE_TRUNC('month', MIN(watch_date)) AS cohort_month
  FROM video_watches
  GROUP BY user_id
),
user_periods AS (
  SELECT 
    vw.user_id,
    c.cohort_month,
    DATE_TRUNC('month', vw.watch_date) AS activity_month,
    (EXTRACT(YEAR FROM vw.watch_date) - EXTRACT(YEAR FROM c.cohort_month)) * 12 
      + (EXTRACT(MONTH FROM vw.watch_date) - EXTRACT(MONTH FROM c.cohort_month)) AS period_number,
    vw.watch_duration_minutes
  FROM video_watches vw
  JOIN cohorts c ON vw.user_id = c.user_id
)
SELECT 
  cohort_month,
  period_number,
  COUNT(DISTINCT user_id) AS active_users,
  AVG(watch_duration_minutes) AS avg_watch_time
FROM user_periods
GROUP BY cohort_month, period_number
ORDER BY cohort_month, period_number;

业务洞察:观看时长是参与度的重要指标。如果某个队列的观看时长下降,可能需要改进内容推荐算法。

4. 移动应用会话队列

场景:你想知道不同队列的用户会话频率。

查询:

sql 复制代码
WITH cohorts AS (
  SELECT user_id, DATE_TRUNC('month', MIN(session_start)) AS cohort_month
  FROM app_sessions
  GROUP BY user_id
),
user_periods AS (
  SELECT 
    s.user_id,
    c.cohort_month,
    DATE_TRUNC('month', s.session_start) AS activity_month,
    (EXTRACT(YEAR FROM s.session_start) - EXTRACT(YEAR FROM c.cohort_month)) * 12 
      + (EXTRACT(MONTH FROM s.session_start) - EXTRACT(MONTH FROM c.cohort_month)) AS period_number
  FROM app_sessions s
  JOIN cohorts c ON s.user_id = c.user_id
)
SELECT 
  cohort_month,
  period_number,
  COUNT(DISTINCT user_id) AS active_users,
  COUNT(*) AS total_sessions,
  COUNT(*) * 1.0 / COUNT(DISTINCT user_id) AS sessions_per_user
FROM user_periods
GROUP BY cohort_month, period_number
ORDER BY cohort_month, period_number;

业务洞察:会话频率反映用户粘性。如果某个队列的会话频率低,可能需要改进推送通知或应用内提示。

跨数据库实现

不同数据库的队列分析实现略有不同,主要是日期函数的差异。

PostgreSQL

sql 复制代码
WITH cohorts AS (
  SELECT 
    user_id,
    DATE_TRUNC('month', MIN(activity_date)) AS cohort_month
  FROM user_activity
  GROUP BY user_id
),
user_periods AS (
  SELECT 
    ua.user_id,
    c.cohort_month,
    DATE_TRUNC('month', ua.activity_date) AS activity_month,
    (EXTRACT(YEAR FROM ua.activity_date) - EXTRACT(YEAR FROM c.cohort_month)) * 12 
      + (EXTRACT(MONTH FROM ua.activity_date) - EXTRACT(MONTH FROM c.cohort_month)) AS period_number
  FROM user_activity ua
  JOIN cohorts c ON ua.user_id = c.user_id
)
SELECT 
  cohort_month,
  period_number,
  COUNT(DISTINCT user_id) AS active_users
FROM user_periods
GROUP BY cohort_month, period_number
ORDER BY cohort_month, period_number;

MySQL

sql 复制代码
WITH cohorts AS (
  SELECT 
    user_id,
    DATE_FORMAT(MIN(activity_date), '%Y-%m-01') AS cohort_month
  FROM user_activity
  GROUP BY user_id
),
user_periods AS (
  SELECT 
    ua.user_id,
    c.cohort_month,
    DATE_FORMAT(ua.activity_date, '%Y-%m-01') AS activity_month,
    TIMESTAMPDIFF(MONTH, c.cohort_month, ua.activity_date) AS period_number
  FROM user_activity ua
  JOIN cohorts c ON ua.user_id = c.user_id
)
SELECT 
  cohort_month,
  period_number,
  COUNT(DISTINCT user_id) AS active_users
FROM user_periods
GROUP BY cohort_month, period_number
ORDER BY cohort_month, period_number;

SQL Server

sql 复制代码
WITH cohorts AS (
  SELECT 
    user_id,
    DATEFROMPARTS(YEAR(MIN(activity_date)), MONTH(MIN(activity_date)), 1) AS cohort_month
  FROM user_activity
  GROUP BY user_id
),
user_periods AS (
  SELECT 
    ua.user_id,
    c.cohort_month,
    DATEFROMPARTS(YEAR(ua.activity_date), MONTH(ua.activity_date), 1) AS activity_month,
    DATEDIFF(MONTH, c.cohort_month, ua.activity_date) AS period_number
  FROM user_activity ua
  JOIN cohorts c ON ua.user_id = c.user_id
)
SELECT 
  cohort_month,
  period_number,
  COUNT(DISTINCT user_id) AS active_users
FROM user_periods
GROUP BY cohort_month, period_number
ORDER BY cohort_month, period_number;

SQLite

sql 复制代码
WITH cohorts AS (
  SELECT 
    user_id,
    DATE(MIN(activity_date), 'start of month') AS cohort_month
  FROM user_activity
  GROUP BY user_id
),
user_periods AS (
  SELECT 
    ua.user_id,
    c.cohort_month,
    DATE(ua.activity_date, 'start of month') AS activity_month,
    (CAST(strftime('%Y', ua.activity_date) AS INTEGER) - CAST(strftime('%Y', c.cohort_month) AS INTEGER)) * 12 
      + (CAST(strftime('%m', ua.activity_date) AS INTEGER) - CAST(strftime('%m', c.cohort_month) AS INTEGER)) AS period_number
  FROM user_activity ua
  JOIN cohorts c ON ua.user_id = c.user_id
)
SELECT 
  cohort_month,
  period_number,
  COUNT(DISTINCT user_id) AS active_users
FROM user_periods
GROUP BY cohort_month, period_number
ORDER BY cohort_month, period_number;

性能优化

队列分析查询可能很慢,特别是对于大型数据集。以下是一些优化建议:

1. 添加索引

sql 复制代码
-- 为 user_id 和 activity_date 添加索引
CREATE INDEX idx_user_activity_user_date ON user_activity(user_id, activity_date);

2. 使用物化视图

sql 复制代码
-- 创建物化视图(PostgreSQL)
CREATE MATERIALIZED VIEW cohort_retention_mv AS
WITH cohorts AS (...),
     user_periods AS (...)
SELECT * FROM user_periods;

-- 定期刷新
REFRESH MATERIALIZED VIEW cohort_retention_mv;

3. 分区表

sql 复制代码
-- 按月份分区(PostgreSQL)
CREATE TABLE user_activity (
  user_id INT,
  activity_date DATE,
  ...
) PARTITION BY RANGE (activity_date);

CREATE TABLE user_activity_2024_01 PARTITION OF user_activity
FOR VALUES FROM ('2024-01-01') TO ('2024-02-01');

4. 限制时间范围

sql 复制代码
-- 只分析最近 12 个月的数据
WITH cohorts AS (
  SELECT user_id, DATE_TRUNC('month', MIN(activity_date)) AS cohort_month
  FROM user_activity
  WHERE activity_date >= CURRENT_DATE - INTERVAL '12 months'
  GROUP BY user_id
)
...

结论

队列分析对于理解用户随时间的行为至关重要。通过根据用户加入时间对用户进行分组并跟踪他们的活动,你可以:

  • 衡量留存率并识别流失点
  • 比较队列以查看产品变更的影响
  • 预测流失并在用户离开之前采取行动

而且使用 SQL,你可以完全控制分析------无需等待第三方工具添加你需要的功能。

关键要点:

  1. 队列分析的核心是将用户按首次互动时间分组,跟踪他们的后续行为
  2. 三步法:识别队列 → 计算周期数 → 构建留存矩阵
  3. 留存率是最重要的指标,但你也可以计算收入、流失率、LTV 等
  4. 最佳实践:选择合适的队列窗口、明确定义"活跃"、使用 CTE、创建视图
  5. 跨数据库:主要差异在于日期函数,核心逻辑相同
  6. 性能优化:索引、物化视图、分区表、限制时间范围

现在去构建一些队列吧!📊


相关文章推荐


版权声明 :本文转载自 SQL Boy,原文链接:https://www.hisqlboy.com/blog/cohort-analysis-with-sql

相关推荐
许彰午4 小时前
01-Oracle数据库简介与版本选择
数据库·oracle
菜鸟~noob2334 小时前
【电子战】第三季预告—波武器与电子系统强力毁伤
开发语言·数据库·matlab·电子战
Seraphina366 小时前
SQL注入(二)盲注
网络·数据库·经验分享·笔记·sql
盟接之桥7 小时前
AI助手:你的7×24小时智能管家——让异常预警无处不在
大数据·网络·数据库·人工智能·制造·ai编程
waoooqwe7 小时前
问卷样本真实吗
大数据·数据库·算法·数据分析
可乐ea8 小时前
Agent 评测换判据:用终态数据库状态判定任务是否完成
数据库·ui·oracle·mcp工具·agent评测·终态断言·智能体可靠性
l1t8 小时前
DeepSeek总结的一个不含数据的 DuckDB 数据库
服务器·数据库·duckdb
PaperData9 小时前
2007-2020年税收调查面板数据
数据库
程序员清风9 小时前
CSV、Excel 与数据库数据读取实践
数据库·oracle·excel
GEO实战经验分享9 小时前
GEO技术与工具全景:从监测仪表盘到Schema的实战指南
数据库