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

将MS Access透视查询适配至SQL Server并补充统计列需求

问题

将MS Access数据库迁移至SQL Server后,原有透视查询无法适配。原Access查询如下:

TRANSFORM FIRST(eff.efi) AS efici

SELECT eff.semana_ano, FIRST(eff.data), LAST(eff.data), ROUND(Avg(eff.efi), 2) AS media_semana
FROM 
    (SELECT dia_semana, semana_ano, efi 
     FROM tmp_lista) AS eff 
GROUP BY eff.semana_ano
PIVOT eff.ndia_semana

SQL Server中的表结构及数据:

CREATE TABLE tmp_lista
(   
    dia         date, 
    dia_semana  varchar(5), 
    semana_ano  int,
    efi         decimal(5,2) 
);

INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-01', 'D5', 5, 0.98);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-02', 'D6', 5, 0.5);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-03', 'D7', 5, NULL);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-04', 'D1', 6, NULL);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-05', 'D2', 6, 0.49);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-06', 'D3', 6, 0.65);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-07', 'D4', 6, 0.3);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-08', 'D5', 6, 1.18);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-09', 'D6', 6, NULL);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-10', 'D7', 6, NULL);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-11', 'D1', 7, NULL);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-12', 'D2', 7, 0.57);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-13', 'D3', 7, NULL);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-14', 'D4', 7, 0.51);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-15', 'D5', 7, 0.65);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-16', 'D6', 7, 0.49);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-17', 'D7', 7, NULL);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-18', 'D1', 8, NULL);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-19', 'D2', 8, 0.34);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-20', 'D3', 8, 0.46);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-21', 'D4', 8, 0.43);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-22', 'D5', 8, 0.32);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-23', 'D6', 8, 0.62);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-24', 'D7', 8, NULL);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-25', 'D1', 9, NULL);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-26', 'D2', 9, 0.62);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-27', 'D3', 9, 0.44);
INSERT INTO tmp_lista (dia, dia_semana, semana_ano, efi) VALUES ('2024-02-28', 'D4', 9, 0.54);

已完成基础透视查询适配:

SELECT
    semana_ano, D1, D2, D3, D4, D5, D6, D7 
FROM
    (SELECT dia_semana, semana_ano, efi FROM tmp_lista) AS dp 
PIVOT
    (SUM(efi) FOR dia_semana IN (D1, D2, D3, D4, D5, D6, D7)) result_dp;

现需补充周最小日期(min(dia))、周最大日期(max(dia))及7天平均值(avg(7 dias))列,期望结果格式:

semana_ano|D1    |D2    |D3    |D4    |D5    |D6    |D7    |min(dia)  |max(dia)  |avg(7 dias)|
----------|------|------|------|------|------|------|------|----------|----------|-----------|
5         |[NULL]|[NULL]|[NULL]|[NULL]|  0.98|  0.50|[NULL]|2024-02-01|2024-02-03|   0.74|
6         |[NULL]|  0.49|  0.65|  0.30|  1.18|[NULL]|[NULL]|2024-02-04|2024-02-10|   0.66|
7         |[NULL]|  0.57|[NULL]|  0.51|  0.65|  0.49|[NULL]|2024-02-11|2024-02-17|   0.56|
8         |[NULL]|  0.34|  0.46|  0.43|  0.32|  0.62|[NULL]|2024-02-18|2024-02-24|   0.43|
9         |[NULL]|  0.62|  0.44|  0.54|[NULL]|[NULL]|[NULL]|2024-02-25|2024-02-28|   0.53|
解决方案

通过先聚合周维度统计数据,再与透视结果关联的方式实现需求,完整SQL语句如下:

WITH WeeklyStats AS (
    SELECT
        semana_ano,
        MIN(dia) AS min_dia,
        MAX(dia) AS max_dia,
        ROUND(AVG(efi), 2) AS avg_7dias
    FROM tmp_lista
    GROUP BY semana_ano
),
PivotedData AS (
    SELECT
        semana_ano,
        D1, D2, D3, D4, D5, D6, D7
    FROM (
        SELECT dia_semana, semana_ano, efi 
        FROM tmp_lista
    ) AS dp
    PIVOT (
        SUM(efi) FOR dia_semana IN (D1, D2, D3, D4, D5, D6, D7)
    ) AS result_dp
)
SELECT
    ps.semana_ano,
    ps.D1, ps.D2, ps.D3, ps.D4, ps.D5, ps.D6, ps.D7,
    ws.min_dia,
    ws.max_dia,
    ws.avg_7dias
FROM PivotedData ps
JOIN WeeklyStats ws ON ps.semana_ano = ws.semana_ano
ORDER BY ps.semana_ano;

说明

  1. WeeklyStats CTE:按semana_ano分组,计算每周的最小日期、最大日期和efi的平均值(保留两位小数),对应原Access查询的media_semana。
  2. PivotedData CTE:复用已完成的基础透视查询,得到按天维度透视的结果。
  3. 关联查询:将两个CTE通过semana_ano关联,合并得到完整的期望结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 02:42:02