查询 and/or 函数,该函数将一个字段上的数据子集用于所有类型并计算其他字段

Query and/or function that subsets the data on one field for all types and calcs on other field

我正在尝试从这里开始:

+------+------+------+------+
| fld1 | fld2 | fld3 | etc… |
+------+------+------+------+
| a    |    5 |    1 |      |
| b    |    5 |    0 |      |
| c    |    6 |    0 |      |
| b    |    2 |    5 |      |
| b    |    1 |    6 |      |
| c    |    0 |    6 |      |
| a    |    8 |    9 |      |
+------+------+------+------+

收件人:

+--------+--------+-----------+-----+-----+------+
| Factor |  Agg   | CalcDate  | Sum | Avg | etc… |
+--------+--------+-----------+-----+-----+------+
| fld2   | fld1/a | 8/14/2015 |  13 | 6.5 |      |
| fld2   | fld1/b | 8/14/2015 |   8 | 2.7 |      |
| fld2   | fld1/c | 8/14/2015 |   6 | 3   |      |
| fld3   | fld1/a | 8/14/2015 |  10 | 5   |      |
| fld3   | fld1/b | 8/14/2015 |  11 | 3.7 |      |
| fld3   | fld1/c | 8/14/2015 |   6 | 3   |      |
+--------+--------+-----------+-----+-----+------+

备注:

Edit1:我上面提供的代码只是为了说明我的尝试和计算。我很确定它与好的答案没有直接关系,但我不是 100% 确定。如果我使用上面的内容,它一次生成一条记录,我必须一次添加(INSERT INTO)每条记录,这会很慢。我的计划是构建一个二维结果数组并使用该二维数组批量添加记录,但被告知如果不循环遍历数组一次添加每条记录就不能这样做,这会破坏目的。我很确定一个解决方案,包括循环遍历 fld1 类型或一个带有子查询的查询,可以在一个步骤中完成,这是应该采取的方向。到目前为止我为优化所做的工作:我将 Excel 对象的创建拉出,因此只在 TestIt() Sub 中创建一次。

Edit2:我有 1305 个字段需要计算。他们不都是一样的table;但是,出于这个问题的目的,我只需要一个一次可以处理多个字段的有效答案。 IE。您的答案可以假设所有字段都在相同的 table 中,为简单起见,您的答案可以只包含 2 个字段,我可以从那里扩展它。在上面的代码中,我在一个字段 "Rk-IU Mkt Cap" 上计算了 12 个指标,聚合了一种类型,'Consumer Discretionary' ([GICS Sector] = 'Consumer Discretionary'")。我拥有的不是我想要的.

如果只使用纯 tSql,这样的东西行得通吗?

1:创建table并插入一些示例数据

CREATE TABLE [dbo].[FLD](
    [fld1] [nvarchar](2) NOT NULL,
    [fld2] [int] NULL,
    [fld3] [int] NULL
) ON [PRIMARY]

GO

INSERT FLD VALUES ('a', 5, 9)
INSERT FLD VALUES ('b', 1, 8)
INSERT FLD VALUES ('a', 3, 7)

2:使用嵌套 UNPIVOT 来创建因子

SELECT t.factor,t.val + '/' + t.v  AS Agg, SUM(value) AS [Sum], AVG(value) AS [AVG]
FROM
(
    SELECT * from
    (
        select * from FLD f
        UNPIVOT
        (
            v
            for val in (fld1)
        ) piv
        ) f
    UNPIVOT 
    (
        value
        for factor in (fld2, fld3)
    ) s
) t 
group by t.v, t.factor, t.val

这将是 Access 数据库引擎要处理的一大难题。它只会让你的数据集增长变得更糟。我建议获取 SQL Server Express 的免费版本,并仅将 Access 用作前端界面。然后随着您的成长,您可以将所有数据库移动到 SQL 服务器……这是一个更强大的数据库引擎。你会很高兴你现在学会了。

SQL Server Express

如果你走这条路,你可以完全使用 T-SQL 和完全基于集合的方法来完成这一切。加速将是剧烈的。我不能在这里给你所有的细节,但总的来说这是你需要做的。在线文档和 Google 可以帮助您完成每个步骤:

  1. 安装SQL服务器Express
  2. 创建数据库
  3. 将您的数据从访问 table 迁移到您的数据库。
  4. 创建一个存储过程来更新您的聚合 table。 (见下文)
  5. 如果您想要访问前端...我建议您创建一个新的 ADP(访问项目文件)并将其连接到您的 SQL 服务器数据库。您将能够根据您的 SQL 服务器 table 和 运行 过程创建表单和报告。但您也可以只使用标准访问项目并使用传递查询来获取数据或 运行 过程。

如果您将第一个 table 结构更改为如下所示,则将数据插入聚合 table 的过程会更容易:

+------+------+------+
| fld1 |fname | fval |
+------+------+------+
| a    | fld2 |    5 |
| a    | fld2 |    8 |
| b    | fld2 |    5 |
| b    | fld2 |    2 |
| b    | fld2 |    1 |
| c    | fld2 |    6 |
| c    | fld2 |    0 |
| a    | fld3 |    1 |
| a    | fld3 |    9 |
| b    | fld3 |    0 |
| b    | fld3 |    5 |
| b    | fld3 |    6 |
| c    | fld3 |    0 |
| c    | fld3 |    6 |
+------+------+------+

虽然您可能不想更改基础数据 table 结构;如果没有,您可以创建一个视图作为一个大联合查询,以这种格式输出它:

select fld1,
    'fld2' fname,
    fld2 fval
from OrigDataTable
union all
select fld1,
    'fld3' fname,
    fld3 fval
from OrigDataTable
union all
...etc

那么您插入聚合数据的查询将类似于:

insert into AggreateTable
select Fname, 
    fld1,
    CONVERT(date, getdate()) CalcDate,
    SUM(fval) sum,
    AVG(Fval) avg,
    ...etc.
from DataTable
Group by Fname, fld1

以下是一些有助于构建聚合函数表达式的链接:

如果您想使用 Access 尝试这种方法,这些可能会有所帮助:

您可能会得到类似这种方法的方法来完全在访问中工作...但我真的认为访问会处理太多...如果不是今天某个时候的话。

你需要的是一个支点table.

你有两个选择:

迁移到 SQL 服务器

这是首选方法,然后您可以像@Johnv2020 建议的那样使用T-SQL

要在 sql 服务器中阅读有关 PIVOTUNPIVOT 的更多信息,click here

Access/Excel 枢轴 table

我个人比较熟悉Excel的pivottable,但是access好像也是这个概念(see here)。

您的代码的预期结果基本上是 运行 多个 数据透视表 tables,具有不同的聚合(平均值,总和, ...),这可以通过使用 VBA

自动化枢轴 tables 来完成

这在 MS Access 中似乎并不难。如果我的逻辑正确:

select "fld2" as factor, "fld1/"&fld1, #8/14/2015# as calcdate,
       sum(fld2), avg(fld2)
from table
group by fld1
union all
select "fld3" as factor, "fld1/"&fld1, #8/14/2015# as calcdate,
       sum(fld3), avg(fld3)
from table
group by fld1;