SQL for MS ACCESS 链接表转置行和列

Posted

技术标签:

【中文标题】SQL for MS ACCESS 链接表转置行和列【英文标题】:SQL for MS ACCESS linked table to transpose rows and columns 【发布时间】:2017-09-27 01:17:25 【问题描述】:

我在这里查看了许多 SQL 转置线程,它们都处理重组数据和/或数据摘要。我有一个不符合任何这些情况的常见情况。 请记住,这是在 MS Access 中,并使用链接表(因此,不允许更新,也没有密钥或 ID)。

我有链接表。只有两行长数据。 比如说,它是一个独特的业务单位 (BU) 和相应的年销售额的列表。

linked_table


     F1     F2     F3     F4    F5  ...
     -----------------------------
row1 BU11   BU123  BU223  BU2   BU432...
row2 $2345  $0     $50.50 $234  $567.22

我需要这个数据集以某种方式转换成这个:

new_table or new_query

BU       Sales
---------------
BU11     $2345
BU123    $0
BU223    $50.50
BU2      $234
BU342    $567.22
...

同样,链接的 Access 表中只有两行长数据。 我只找到了一种非常乏味和丑陋的方法来解决这个问题,并且想知道是否有更好的方法来做到这一点。

第 1 步 我已将两行数据分成 2 个单独的查询

headers_qry
     F1     F2     F3     F4    F5...
     ------------------------------
row1 BU11   BU123  BU223  BU2   BU432...

data_qry
     F1     F2     F3     F4    F5...
     ------------------------------
row1 $2345  $0     $50.50 $234  $567.22...

然后我将一个虚拟的“公共密钥”硬编码到两个数据集中

headers_qry
     F1     F2     F3     F4    F5...       KEY
     ----------------------------------------------
row1 BU11   BU123  BU223  BU2   BU432...    UNIQUE123

data_qry
     F1     F2     F3     F4    F5...       KEY
     -----------------------------------------------
row1 $2345  $0     $50.50 $234  $567.22...  UNIQUE123

然后,我在该公共键上的两个查询之间添加了一个连接,并通过数百个 UNION 语句手动配对 Header 和 Data 对。哎哟!!!!

SELECT 
headers.F1 AS BU_Number,
data.F1 AS BU_Sales 
FROM header_data_join_qry UNION ALL
SELECT 
headers.F2 AS BU_Number,
data.F2 AS BU_Sales 
FROM header_data_join_qry UNION ALL
SELECT 
...
headers.F100 AS BU_Number,
data.F100 AS BU_Sales 
FROM header_data_join_qry UNION ALL;

这不仅乏味且难看,MS ACCESS 还无法处理这些多个 UNION ALL 查询,一旦我达到 100 个左右,它就开始给出 SQL 语句太复杂的错误。

考虑到链接源表和 MS ACCESS SQL 环境的限制,有没有办法更好地处理这个问题?非常感谢!

【问题讨论】:

你达到了 100?我认为 50 是 UNION 中 SELECT 行的限制。我知道的唯一替代方法是 VBA 将记录写入临时表 - 表是永久的,数据是临时的。 看看第三个答案here。也许它会帮助你 我通过分成 2 个子查询获得了 100 分。之后,我也将两者联合起来。这将 ACCESS 容差提高到 50 以上... 【参考方案1】:

你可以试试下面的方法。

从分隔两行数据的起始位置开始,不需要公共键(因为它们都是一行)。

SELECT DLookUp("F" & Number, "headers_qry") AS BU, DLookUp("F" & Number, "data_qry") As Sales
FROM (
SELECT DISTINCT Abs(Ones.ID Mod 10) + Abs(Tens.ID Mod 10) * 10 + Abs(Hundreds.ID Mod 10)*100 As Number 
FROM MSysObjects As Ones, MSysObjects As Tens, MSysObjects As Hundreds
) As NumbersQuery
WHERE Number BETWEEN 1 And 200

基本上,这个查询有两部分:

    返回 0 到 999 之间每个数字的子查询(技术改编自 Gustav) 从您的两个查询中返回指定列号并过滤子查询的外部查询。

BETWEEN 1 And 200 可以适应您的样本

如果需要更大的数字(0 到 9999),也可以调整子查询

【讨论】:

这是火。谢谢! @CamCall 如果这回答了您的问题,请将答案标记为已接受。阅读here,了解它的工作原理以及优势。 我必须说它在返回记录之前在无响应状态下运行了 10 分钟。 因为我没有声誉(笑)我不能投票或接受答案。感谢您的帮助! 长时间无响应状态是正常的。 DLookUp 和生成数字的子查询都是非常繁重的操作,并且需要时间。您可以通过使用带有数字的表而不是该子查询来优化它,但是使用 DLookUp 数百次仍然需要时间(每行调用两次)。

以上是关于SQL for MS ACCESS 链接表转置行和列的主要内容,如果未能解决你的问题,请参考以下文章

用awk转置行和列

更新 MS Access 表转置结构和更新字段

仅使用最小 COUNT() 转置行和列(又名枢轴)?

当 BigQuery 中没有任何“id”类型列时转置行和列

如何在Django excel导出文件中转置行和列

在 SQL Server 表中加入和分组后转置行