当前位置: 首页 > article >正文

沐数科技数据开发岗笔试题2025

描述性统计

标准差 

答案: A

解析:

标准差

衡量数据集中数值变化或离散程度的一种度量。它反映了数据集中的各个数值与数据集的平均值(均值)之间的偏离程度。标准差越大,表明数据的分布越分散;标准差越小,表明数据越集中

标准差的取值范围是[0, +∞)

标准差是方差的平方根

在有限的数据集中,标准差不可能大于数据集中的最大值与最小值之差的一半

均值, 即平均值 

正态分布

也被称为高斯分布(Gaussian distribution)

特征

  1. 对称性:正态分布曲线关于均值对称,均值所在的垂直线将曲线分为两个镜像部分。

  2. 钟形曲线:分布曲线呈现为钟形,均值处达到最高点,向两侧逐渐降低。

  3. 均值、中位数和众数相等:在正态分布中,均值(平均值)、中位数(数据中间值)和众数(出现次数最多的值)是相等的。

  4. 68-95-99.7规则:在正态分布中,大约68%的数据值落在距离均值一个标准差的范围内,约95%的数据值落在两个标准差的范围内,而约99.7%的数据值落在三个标准差的范围内。

中位数

答案: B 

解析:

A. 所有数据的平均值,  是所有数据值加起来除以数据个数得到的值。

C. 最小值和最大值的平均值, 这通常被称为数据集的中点(Midrange)

D. 数据按降序排列后的第一个值, 这个值实际上是数据集的最大值(Maximum)

数据探查

数据清洗 

答案: C

解析:

数据清洗的步骤

检查缺失值和异常值>>数据格式化>>数据合并>>生成报告

检查数据分布

答案: B

解析:

A. 折线图(Line Chart)

  • 用于展示数据随时间或有序类别变化的趋势。

  • 适合展示连续数据和时间序列数据的变化情况。

  • 可以清晰地显示数据的增减变化和预测未来的趋势。

B. 直方图(Histogram)

  • 用于展示数据分布的情况。

  • 通过将数据分成若干个区间(bins),展示每个区间内数据的频率或数量。

  • 适合检查数据的分布形态,如是否接近正态分布,以及数据的集中趋势和离散程度。

C. 散点图(Scatter Plot)

  • 用于展示两个变量之间的关系。

  • 通过在二维平面上绘制点,可以观察两个变量之间是否存在相关性。

  • 适合探索变量之间的相关性、趋势和模式。

D. 热力图(Heatmap)

  • 用颜色变化来展示矩阵或表格中数据的大小。

  • 适合展示两个类别变量之间的关系,如时间序列数据的周期性变化。

  • 常用于展示数据的密度或强度,如地理热力图、用户行为热力图等。

主键

答案: A

解析:

主键约束: 唯一且非空

主键

答案: A

解析:

A.  

  1. 业务逻辑错误:逻辑主键用于确保数据的一致性和准确性。如果主键不唯一,可能会插入重复的记录,导致业务逻辑错误。

  2. 数据扩散:在数据扩散(Data Replication)过程中,如果主键不唯一,可能会导致数据不一致,因为相同的主键值可能会被复制到多个位置。

  3. 数据不一致:由于重复的主键值,可能会导致数据更新或删除操作影响到错误的记录,从而造成数据不一致。

数据扩散(Data Replication)是将数据从一个位置复制到另一个位置的过程,以确保数据的可用性、冗余和容错性

B.  主键不唯一  可能因为重复值导致索引效率降低。

C. 主键不唯一,查询操作仍然可以关联到数据,只是可能会关联到多条记录,而不是预期的单条记录。

D. 相反,主键的定义就是为了确保唯一性,如果违反了这一约束,数据库通常会报错,需要手动干预来解决重复主键的问题。

连续型变量

答案: D

解析: 

连续型变量(Continuous Variable)是指可以在无限或有限的区间内取任意值的变量。

离散型变量(Discrete Variable)只能取有限个或可数无限个值,如人数、车辆数、产品数量等

连续型变量的离群点(Outliers)是指在数据集中与其他数据点明显不同或者异常的数据点。这些数据点可能比其他数据点要远离数据集的中心,或者具有异常的数值。离群点可能是由于数据采集错误、异常事件、测量误差或者其他未知因素引起的。离群点的存在可以对数据分析和统计建模产生重要影响,因为它们可能导致模型不准确或者产生误导性的结果。

数据缺失值

答案: B

解析:

A. 用前一天的数据填充缺失值

  • 这种方法假设数据在短期内是稳定的,前一天的数据可以作为当天数据的合理代理。这种方法简单易行,但可能不适用于数据波动较大的情况

B. 检查缺失值是否集中在特定的时间段

  • 通过检查缺失值的分布,可以了解数据缺失是否具有某种模式。例如,如果缺失值集中在特定的时间段,可能表明数据收集过程中存在系统性问题,如设备故障或节假日效应。这种方法有助于识别数据缺失的原因,从而采取更有针对性的处理措施。

C. 删除所有包含缺失值的日期

  • 删除包含缺失值的日期可以简化分析,但可能会导致信息损失,特别是如果缺失值较多时。这种方法适用于缺失值较少且删除后不会对分析结果产生显著影响的情况。

D. 插值法填充所有缺失值

  • 插值法(如线性插值、多项式插值等)通过使用数据集中的其他数据点来估计缺失值。这种方法可以保留更多的数据信息,但插值的准确性依赖于数据的分布和趋势。插值可能不适用于缺失值较多或缺失模式不规则的情况。

线性差值: 如果两个已知数据点之间的数据变化是线性的,即在这两个点之间,数据的变化率是恒定的。 

多项式插值: 使用一个多项式函数来通过所有已知的数据点。这种方法可以提供比线性插值更复杂的数据模型,适用于数据变化更复杂的情况。

业务

10.实操题

销售订单表

订单明细表

【备注】 - ​业务主键(Business Key)​:指在业务逻辑中唯一标识一条记录的字段或字段组合。与数据库中的主键(Primary Key)​有所不同,业务主键(Business Key)​是业务层面的唯一标识,通常由业务规则决定,例如,订单号、订单明细号,身份证号等

【问题】 仅基于这份数据,以下哪些说法正确?(多选)

A. order 表的业务主键存在空值缺失情况

B. order 表的数据时间范围为 从 2009 ~ 2012 年的订单数据

C. order_detail 缺少一个明确的业务主键字段,但是存在业务主键字段组合(order_id + product_id)

D. 华北区中,订单最多的客户(customer)是 SAVEA,Owner 都是 苏先生,一共有16笔订单

E. 一共有77个产品,都有被卖出去;其中单价最高的是 绿茶,其单价为 263.5

答案: A, C, D, E

解析:

B. order 表显示的订单日期从 2010/8/12 开始,一直到 2010/10/8 结束

沐数一下

答案: B、C、D、G、H

解析:

选项 A 提供数据存储服务,通常不是探查报告的直接功能,而是数据管理系统或数据库的角色。

沐数一下

答案: B, C, D

解析:

A 存储数据表的所有数据,通常不是探查报告的直接功能,而是数据库或数据存储系统的角色。

E 对数据表中的值进行清洗和标准化,虽然探查报告可能提供一些数据清洗和标准化的指导,但直接进行这些操作通常需要其他工具或过程。

沐数一下

答案: A, B, C, D, E 

SQL

解析实操题: 

SELECT 
    s.country,
    p.product_id,
    p.product_name,
    SUM(s.amount) AS total_sales
FROM 
    sales s
JOIN 
    products p ON s.product_id = p.product_id
WHERE 
    s.country IN ('法国', '英国')
    AND s.sale_date BETWEEN '2020-09-01' AND '2020-09-30'
GROUP BY 
    s.country,
    p.product_id,
    p.product_name
ORDER BY 
    s.country,
    p.product_id;

输出示例

解析填空题

SELECT 
    p.product_name,
    ROUND(SUM(s.amount), 0) AS total_sales
FROM 
    sales s
JOIN 
    products p ON s.product_id = p.product_id
WHERE 
    s.country = '英国'
    AND s.sale_date BETWEEN '2020-09-01' AND '2020-09-30'
GROUP BY 
    p.product_name
ORDER BY 
    total_sales DESC
FETCH FIRST 1 ROW ONLY;

解析: 

实操题

SELECT 
    s.country,
    SUM(s.amount) AS total_sales,
    CASE 
        WHEN SUM(s.amount) > 10000 THEN '合格'
        ELSE '不合格'
    END AS performance
FROM 
    sales s
GROUP BY 
    s.country
ORDER BY 
    s.country;

 填空题

SELECT 
    s.country,
    ROUND(SUM(s.amount), 0) AS total_sales
FROM 
    sales s
GROUP BY 
    s.country
ORDER BY 
    total_sales DESC
FETCH FIRST 1 ROW ONLY;

解析: 

实操题

SELECT
    p.product_name AS "产品名称",
    SUM(s.sales_amount) AS "销售金额",
    ROUND(SUM(s.sales_amount) / total_sales.total_amount * 100, 2) AS "占比"
FROM
    sales s
JOIN
    products p ON s.product_id = p.product_id
CROSS JOIN
    (SELECT SUM(sales_amount) AS total_amount FROM sales) total_sales
GROUP BY
    p.product_name, total_sales.total_amount
HAVING
    ROUND(SUM(s.sales_amount) / total_sales.total_amount * 100, 2) >= 10
ORDER BY
    "占比" DESC;

CROSS JOIN 的作用是将 sales 表中的每一行与 total_sales 子查询的结果(即总销售金额)进行笛卡尔积连接。这意味着每一行 sales 数据都会与 total_sales 中的总金额进行组合,从而使得每一行都可以访问总销售金额。

填空题

WITH ProductSales AS (
    SELECT
        p.product_name,
        SUM(s.sales_amount) AS total_sales_amount,
        ROUND(SUM(s.sales_amount) / total_sales.total_amount * 100, 2) AS sales_percentage
    FROM
        sales s
    JOIN
        products p ON s.product_id = p.product_id
    CROSS JOIN
        (SELECT SUM(sales_amount) AS total_amount FROM sales) total_sales
    GROUP BY
        p.product_name, total_sales.total_amount
    HAVING
        ROUND(SUM(s.sales_amount) / total_sales.total_amount * 100, 2) >= 10
),
RankedProducts AS (
    SELECT
        sales_percentage,
        DENSE_RANK() OVER (ORDER BY sales_percentage DESC) AS rank
    FROM
        ProductSales
)
SELECT
    COUNT(*) AS product_count,
    MAX(CASE WHEN rank = 3 THEN sales_percentage END) AS third_largest_percentage
FROM
    RankedProducts;

解析: 

实操题

SELECT 
    CASE 
        WHEN age < 25 THEN '25岁以下'
        WHEN age >= 25 AND age < 30 THEN '25-30岁'
        WHEN age >= 30 AND age < 35 THEN '30-35岁'
        WHEN age >= 35 AND age < 40 THEN '35-40岁'
        WHEN age >= 40 AND age < 45 THEN '40-45岁'
        WHEN age >= 45 AND age < 50 THEN '45-50岁'
        WHEN age >= 50 AND age < 55 THEN '50-55岁'
        WHEN age >= 55 THEN '55岁及以上'
        ELSE '异常情况'
    END AS age_group,
    COUNT(*) AS num_employees
FROM employees
WHERE age IS NOT NULL AND age > 0
GROUP BY 
    CASE 
        WHEN age < 25 THEN '25岁以下'
        WHEN age >= 25 AND age < 30 THEN '25-30岁'
        WHEN age >= 30 AND age < 35 THEN '30-35岁'
        WHEN age >= 35 AND age < 40 THEN '35-40岁'
        WHEN age >= 40 AND age < 45 THEN '40-45岁'
        WHEN age >= 45 AND age < 50 THEN '45-50岁'
        WHEN age >= 50 AND age < 55 THEN '50-55岁'
        WHEN age >= 55 THEN '55岁及以上'
        ELSE '异常情况'
    END
ORDER BY 
    CASE 
        WHEN age_group = '25岁以下' THEN 1
        WHEN age_group = '25-30岁' THEN 2
        WHEN age_group = '30-35岁' THEN 3
        WHEN age_group = '35-40岁' THEN 4
        WHEN age_group = '40-45岁' THEN 5
        WHEN age_group = '45-50岁' THEN 6
        WHEN age_group = '50-55岁' THEN 7
        WHEN age_group = '55岁及以上' THEN 8
        ELSE 9
    END;

填空题

WITH AgeDistribution AS (
    SELECT 
        CASE 
            WHEN age < 25 THEN '25岁以下'
            WHEN age >= 25 AND age < 30 THEN '25-30岁'
            WHEN age >= 30 AND age < 35 THEN '30-35岁'
            WHEN age >= 35 AND age < 40 THEN '35-40岁'
            WHEN age >= 40 AND age < 45 THEN '40-45岁'
            WHEN age >= 45 AND age < 50 THEN '45-50岁'
            WHEN age >= 50 AND age < 55 THEN '50-55岁'
            WHEN age >= 55 THEN '55岁及以上'
            ELSE '异常情况'
        END AS age_group,
        COUNT(*) AS num_employees
    FROM employees
    WHERE age IS NOT NULL AND age > 0
    GROUP BY 
        CASE 
            WHEN age < 25 THEN '25岁以下'
            WHEN age >= 25 AND age < 30 THEN '25-30岁'
            WHEN age >= 30 AND age < 35 THEN '30-35岁'
            WHEN age >= 35 AND age < 40 THEN '35-40岁'
            WHEN age >= 40 AND age < 45 THEN '40-45岁'
            WHEN age >= 45 AND age < 50 THEN '45-50岁'
            WHEN age >= 50 AND age < 55 THEN '50-55岁'
            WHEN age >= 55 THEN '55岁及以上'
            ELSE '异常情况'
        END
),
Ranking AS (
    SELECT age_group, num_employees,
           RANK() OVER (ORDER BY num_employees DESC) AS rank
    FROM AgeDistribution
)
SELECT 
    age_group,
    num_employees
FROM Ranking
WHERE rank = 2;

SELECT COUNT(*) AS num异常
FROM employees
WHERE age IS NULL OR age <= 0;

SELECT 
    reason,
    COUNT(*) AS num_people,
    RANK() OVER (ORDER BY COUNT(*) DESC) AS ranking
FROM new_hires
GROUP BY reason
ORDER BY ranking;

填空题

SELECT reason, COUNT(*) AS num_people
FROM new_hires
GROUP BY reason
ORDER BY COUNT(*) DESC
FETCH FIRST 1 ROW ONLY OFFSET 3 ROWS;

解析: 

实操题

SELECT
    YEAR(resignation_date) AS resignation_year,
    COUNT(employee_id) AS num_resignations,
    SUM(COUNT(employee_id)) OVER (ORDER BY YEAR(resignation_date)) AS cumulative_resignations
FROM employee_resignations
GROUP BY YEAR(resignation_date)
ORDER BY resignation_year;

窗口函数 SUM(...) OVER (...) 的行为。它不是在对整个结果集进行求和,而是在对结果集的每个分组(由 GROUP BY 定义)进行求和。

OVER (ORDER BY YEAR(resignation_date)) 定义了窗口函数的操作范围,即按照 resignation_date 的年份进行排序

 填空题

WITH ResignationStats AS (
    SELECT
        YEAR(resignation_date) AS resignation_year,
        COUNT(employee_id) AS num_resignations,
        SUM(COUNT(employee_id)) OVER (ORDER BY YEAR(resignation_date)) AS cumulative_resignations
    FROM employee_resignations
    GROUP BY YEAR(resignation_date)
)
SELECT 
    resignation_year,
    num_resignations
FROM ResignationStats
WHERE cumulative_resignations > 100
ORDER BY resignation_year
FETCH FIRST 1 ROW ONLY;

解析:

实操题

SELECT 
    AVG(CASE WHEN class = 'Class1' THEN score ELSE NULL END) AS class1_avg,
    AVG(CASE WHEN class = 'Class2' THEN score ELSE NULL END) AS class2_avg,
    AVG(CASE WHEN class = 'Class1' THEN score ELSE NULL END) 
    - AVG(CASE WHEN class = 'Class2' THEN score ELSE NULL END) AS difference
FROM 
    scores
WHERE 
    course = 'data_visualization';

填空题

SELECT 
    ROUND(AVG(CASE WHEN class = 'Class1' THEN score ELSE NULL END) 
    - AVG(CASE WHEN class = 'Class2' THEN score ELSE NULL END), 2) AS difference
FROM 
    scores
WHERE 
    course = 'data_visualization';

解析: 

实操题

Oracle 12c及更高版本支持FILTER子句, 用于在聚合函数中过滤数据

SELECT 
    class,
    AVG(score) OVER (PARTITION BY class) AS avg_score,
    COUNT(*) FILTER (WHERE score < AVG(score) OVER (PARTITION BY class)) 
    AS below_avg_count
FROM 
    scores
WHERE 
    course = 'sql'
GROUP BY 
    class;

 Oracle 12c版本以下>>使用子查询和CASE语句来实现相同的功能

SELECT 
    class,
    AVG(score) AS avg_score,
    (SELECT COUNT(*) FROM scores s2 WHERE s2.class = s.class 
    AND s2.score < s.avg_score) AS below_avg_count
FROM 
    scores s
WHERE 
    s.course = 'sql'
GROUP BY 
    class;

子查询中的 s2.class = s.class 确保了子查询只考虑与外部查询中当前处理的班级相同的记录。换句话说,对于每个班级,子查询都会计算该班级中成绩低于班级平均分的学生人数。

填空题

SELECT 
    class,
    AVG(score) AS avg_score,
    COUNT(*) FILTER (WHERE score < AVG(score) OVER (PARTITION BY class)) 
    AS below_avg_count
FROM 
    scores
WHERE 
    course = 'sql'
GROUP BY 
    class
ORDER BY 
    avg_score ASC
FETCH FIRST 1 ROW ONLY;

解析

实操题思路

使用两个CTE表达式>>计算出每月销售额; 计算去年同月的销售额, 计算上个月的销售额

主查询>>计算同比增长率, 环比增长率, 提取需要的字段

数据范围

  • 确保 sales_data 表中包含2019年和2020年的数据,否则同比计算可能不准确

WITH MonthlySales AS (
    -- 假设原始数据表为 sales_data, 包含 sale_date 和 amount 字段
    SELECT
        TO_CHAR(sale_date, 'YYYY') AS sale_year,
        TO_CHAR(sale_date, 'MM') AS sale_month,
        SUM(amount) AS total_sales
    FROM sales_data
    WHERE sale_date >= TO_DATE('2019-01-01', 'YYYY-MM-DD')  -- 包含2019年数据
      AND sale_date < TO_DATE('2021-01-01', 'YYYY-MM-DD')   -- 包含2020年数据
    GROUP BY TO_CHAR(sale_date, 'YYYY'), TO_CHAR(sale_date, 'MM')
),
CTE AS (
    SELECT
        sale_year,
        sale_month,
        total_sales,
        LAG(total_sales, 12) OVER (ORDER BY sale_year, sale_month) AS prev_year_sales, 
        -- 去年同月销售额
        LAG(total_sales, 1) OVER (ORDER BY sale_year, sale_month) AS prev_month_sales  
        -- 上月销售额
    FROM MonthlySales
)
SELECT
    sale_year AS 年份,
    sale_month AS 月份,
    total_sales AS 销售额,
    -- 计算同比增长率
    CASE
        WHEN prev_year_sales IS NOT NULL AND prev_year_sales <> 0 THEN
            (total_sales - prev_year_sales) / prev_year_sales
        ELSE
            NULL
    END AS 同比,
    -- 计算环比增长率
    CASE
        WHEN prev_month_sales IS NOT NULL AND prev_month_sales <> 0 THEN
            (total_sales - prev_month_sales) / prev_month_sales
        ELSE
            NULL
    END AS 环比
FROM CTE
WHERE sale_year = '2020'  -- 只输出2020年的结果
ORDER BY sale_year, sale_month;

填空题

在主查询的where过滤条件增加月份的过滤, 注意格式>>round, to_char(number, format)

WITH MonthlySales AS (
    -- 假设原始数据表为 sales_data, 包含 sale_date 和 amount 字段
    SELECT
        TO_CHAR(sale_date, 'YYYY') AS sale_year,
        TO_CHAR(sale_date, 'MM') AS sale_month,
        SUM(amount) AS total_sales
    FROM sales_data
    WHERE sale_date >= TO_DATE('2019-01-01', 'YYYY-MM-DD')  -- 包含2019年数据
      AND sale_date < TO_DATE('2021-01-01', 'YYYY-MM-DD')   -- 包含2020年数据
    GROUP BY TO_CHAR(sale_date, 'YYYY'), TO_CHAR(sale_date, 'MM')
),
CTE AS (
    SELECT
        sale_year,
        sale_month,
        total_sales,
        LAG(total_sales, 12) OVER (ORDER BY sale_year, sale_month) AS prev_year_sales, 
        -- 去年同月销售额
        LAG(total_sales, 1) OVER (ORDER BY sale_year, sale_month) AS prev_month_sales  
        -- 上月销售额
    FROM MonthlySales
)
SELECT
    ROUND(total_sales) AS 销售额,  -- 四舍五入到整数
    TO_CHAR(
        CASE
            WHEN prev_year_sales IS NOT NULL AND prev_year_sales <> 0 THEN
                (total_sales - prev_year_sales) / prev_year_sales * 100
            ELSE
                NULL
        END, '999.99') || '%' AS 同比,  -- 同比增长率,保留2位小数百分比
    TO_CHAR(
        CASE
            WHEN prev_month_sales IS NOT NULL AND prev_month_sales <> 0 THEN
                (total_sales - prev_month_sales) / prev_month_sales * 100
            ELSE
                NULL
        END, '999.99') || '%' AS 环比  -- 环比增长率,保留2位小数百分比
FROM CTE
WHERE sale_year = '2020' AND sale_month = '09';  -- 只查询2020年9月的数据

 

解析

实操题

WITH RankedResults AS (
    SELECT
        employee_id,
        employee_name,
        statistics,
        sql_score,
        python,
        data_visualization,
        mathematics,
        exam_date,
        (statistics + sql_score + python + data_visualization + mathematics) 
        AS total_score,
        CASE
            WHEN statistics >= 60 AND sql_score >= 60 AND python >= 60 
                AND data_visualization >= 60 AND total_score >= 300 THEN 'pass'
            ELSE 'fail'
        END AS final_result,
        ROW_NUMBER() OVER (PARTITION BY employee_id, final_result 
                            ORDER BY total_score DESC) AS rn
    FROM exam_results
)
SELECT
    employee_id AS 员工ID,
    employee_name AS 人员姓名,
    statistics AS statistics得分,
    sql_score AS SQL得分,
    python AS python得分,
    data_visualization AS data_visualization得分,
    mathematics AS mathematics得分,
    total_score AS 总分,
    exam_date AS 考核时间,
    final_result AS 最终考核结果
FROM RankedResults
WHERE rn = 1  -- 取每个员工通过或未通过中总分最高的记录
ORDER BY employee_id;

填空题

解析

实操题

SELECT 
    ec.COUNTRY AS 国家,
    ep.PRODUCTID AS 产品ID,
    ep.PRODUCTNAME AS 产品名称,
    SUM(ep.PRICE * eo.SALE_AMOUNT) AS 销售金额
FROM 
    e_product ep
LEFT JOIN e_order eo ON ep.PRODUCTID = eo.PRODUCTID
LEFT JOIN e_customer ec ON eo.CUSTOMID = ec.CUSTOMID
WHERE 
    SUBSTR(eo.ZTIME, 1, 7) = '2020-09'
    AND ec.COUNTRY IN ('法国', '英国')
GROUP BY 
    ec.COUNTRY, ep.PRODUCTID, ep.PRODUCTNAME
ORDER BY 
    ec.COUNTRY, ep.PRODUCTID;

填空题

SELECT 
    ep.PRODUCTNAME AS 产品名称,
    ROUND(SUM(ep.PRICE * eo.SALE_AMOUNT)) AS 销售金额
FROM 
    e_customer ec
JOIN e_order eo ON ec.CUSTOMID = eo.CUSTOMID
JOIN e_product ep ON eo.PRODUCTID = ep.PRODUCTID
WHERE 
    ec.COUNTRY = '英国'
    AND TO_CHAR(eo.ZTIME, 'YYYY-MM') = '2020-09'
GROUP BY 
    ep.PRODUCTNAME
ORDER BY 
    SUM(ep.PRICE * eo.SALE_AMOUNT) DESC
FETCH FIRST 1 ROW ONLY;

SELECT 
    DATE(t1.register_time_bj) AS stat_date,  -- 将登录时间转换为日期格式,作为统计日期
    t1.channel,  -- 用户登录的渠道
    COUNT(DISTINCT CASE 
        WHEN t2.credit_submit_time_local BETWEEN t1.register_time_bj AND DATE_ADD(t1.register_time_bj, INTERVAL 3 DAY) 
        THEN t1.uid 
    END) AS credit_submit_cnt,  -- 计算在用户登录后3天内提交授信申请的用户数量
    COUNT(DISTINCT CASE 
        WHEN t2.credit_submit_time_local BETWEEN t1.register_time_bj AND DATE_ADD(t1.register_time_bj, INTERVAL 3 DAY) 
        AND t2.credit_status = 'success' 
        THEN t1.uid 
    END) AS credit_succ_cnt  -- 计算在用户登录后3天内成功授信的用户数量
FROM 
    table_register t1
LEFT JOIN 
    table_credit t2 ON t1.uid = t2.uid  -- 通过用户ID连接两个表
WHERE 
    DATE(t1.register_time_bj) >= DATE_SUB(CURRENT_DATE, INTERVAL 1 MONTH)  -- 筛选最近一个月的数据
GROUP BY 
    DATE(t1.register_time_bj), t1.channel  -- 按日期和渠道聚合
ORDER BY 
    stat_date, t1.channel;  -- 按日期和渠道排序

. 确定数据来源和字段
用户登录表(table_register):包含用户ID(uid)、登录时间(register_time_bj)、渠道(channel)。
用户授信表(table_credit):包含用户ID(uid)、授信申请时间(credit_submit_time_local)、授信状态(credit_status)。
2. 确定时间范围
使用DATE_SUB(CURRENT_DATE, INTERVAL 1 MONTH)来获取当前日期前一个月的日期,确保只统计最近一个月的数据。
3. 连接两个表
使用LEFT JOIN连接table_register和table_credit表,通过uid字段连接。这样可以确保即使某些用户没有授信记录,也能在结果中显示他们的登录信息。
4. 筛选符合条件的记录
使用WHERE子句筛选出登录时间在最近一个月内的记录。
5. 计算授信申请和成功授信的用户数量
使用COUNT(DISTINCT CASE WHEN ... THEN ... END)结构来计算:
授信申请用户数量(credit_submit_cnt):计算在用户登录后3天内提交授信申请的用户数量。
成功授信用户数量(credit_succ_cnt):计算在用户登录后3天内成功授信的用户数量。
6. 聚合和排序结果
使用GROUP BY子句按日期和渠道对结果进行聚合。
使用ORDER BY子句按日期和渠道对结果进行排序。


http://www.kler.cn/a/588979.html

相关文章:

  • 《C#上位机开发从门外到门内》3-2::Modbus数据采集系统
  • HTTP+DNS综合实验
  • 谷粒商城:性能压测JVM堆区
  • C# Winform 实现换肤,并自定义皮肤功能
  • C#—闭包详解
  • 群体智能优化算法-旗鱼优化算法 (Sailfish Optimizer, SFO,含Matlab源代码)
  • SQL Server表数据变更捕获的5种方法及实战对比
  • C++(初阶)(五)——类和对象(下)
  • 【极光 Orbit·STC8x】05. GPIO库函数驱动LED流动
  • 【区块链+乡村振兴】四川云龙肉牛产业数字化平台 | FISCO BCOS 应用案例
  • 操作系统八股文整理(一)
  • Celery在Django中的作用
  • day05_Java高级
  • 深度学习正则化技术之权重衰减法、暂退法(通俗易懂版)
  • 一款基于Python的从常规文档里提取图片的简单工具开发方案
  • 30、Vuex 为啥可以进行缓存处理
  • 【Leetcode 每日一题】3306. 元音辅音字符串计数 I
  • linux:环境变量,进程地址空间
  • 网络编程基础
  • 算法日记41:思维提升(最大gcd+好数组+简单的减法+球的颜色)