繁体   English   中英

具有分组和未分组总和的MS Excel SQL查询

[英]MS Excel SQL query with grouped and not grouped sum

我正在使用VBA宏,并尝试对Excel工作表中的表执行查询。 我的查询从对所有文本字段和布尔字段进行区分的简单选择开始。 我需要它们之间的所有可能组合以及它们的总和。 我的桌子(缩写)看起来像

Txt1    Txt2    Txt3    Amt1    Amt2    Bool1   Bool2   Bool3
A       B          F    10      1000    YES     YES     YES
A       D          F    20       200    YES     YES     YES
A       B          F    5        100    YES     YES     YES
A       B          G    10      1200    NO      YES     NO
A       D          H    5       1300    NO      YES     NO
A       B          I    30       500    YES     YES     NO
A       B          J    10       600    YES     YES     YES
A       D          K    6        800    YES     YES     YES
A       B          F    4       1000    NO      YES     YES
A       B          F    2       2900    NO      YES     NO
A       D          F    6       3150    YES     YES     NO
A       B          F    1       3400    YES     YES     NO
A       B          F    0       3650    YES     YES     YES
A       D          F    5       3900    NO      YES     YES
A       B          H    15      4150    NO      YES     YES
A       B          F    2       4400    YES     YES     NO
A       D          F    1       4650    YES     YES     NO
A       B          F    5       4900    YES     YES     NO
A       B          G    6       5150    NO      NO      YES
A       D          H    8       5400    NO      NO      YES
A       B          I    2        100    YES     YES     YES

这是我获得此代码的地方:

SELECT DISTINCTROW [Txt1], [Txt2], [Txt3], [Bool1], [Bool2], [Bool3], Sum([Amt1]) AS [Sum Amt1], Sum([Amt2]) AS [Sum Amt2] 
FROM [mytable] 
GROUP BY [Txt1], [Txt2], [Txt3], [Bool1], [Bool2], [Bool3];

它的工作原理是:

Txt1   Txt2   Txt3   Bool1   Bool2   Bool3   Sum Amt1   Sum Amt2
    A     B     F     NO     YES     NO       2               2900
    A     B     F     NO     YES     YES      4               1000
    A     B     F     YES    YES     NO       8               12700
    A     B     F     YES    YES     YES      15              4750
    A     B     G     NO     NO      YES      6               5150
    A     B     G     NO     YES     NO       10              1200
    A     B     H     NO     YES     YES      15              4150
    A     B     I     YES    YES     NO       30              500
    A     B     I     YES    YES     YES      2               100
    A     B     J     YES    YES     YES      10              600
    A     D     F     NO     YES     YES      5               3900
    A     D     F     YES    YES     NO       7               7800
    A     D     F     YES    YES     YES      20              200
    A     D     H     NO     NO      YES      8               5400
    A     D     H     NO     YES     NO       5               1300
    A     D     K     YES    YES     YES      6               800

但是我真正需要的是与一个字段/列相同的字段/列,该字段对“文本”字段之间的每个组合求和,甚至更好的是包括“布尔”字段的摘要行。 如果我做:

SELECT DISTINCTROW [Txt1], [Txt2], [Txt3], Sum([Amt1]) AS [Sum Amt1], Sum([Amt2]) AS [Sum Amt2] 
FROM [mytable] 
GROUP BY [Txt1], [Txt2], [Txt3];

我摆脱了布尔字段并获得摘要,但是这种情况是我不知道如何将两个查询放在一起。

Txt1   Txt2 Txt3    Sum Amt1    Sum Amt2
A       B      F       29      21350
A       B      G       16       6350
A       B      H       15       4150
A       B      I       32        600
A       B      J       10        600
A       D      F       32      11900
A       D      H       13       6700
A       D      K        6        800

我尝试将伪布尔值列添加到表中,并将伪字段添加到查询中(同时将select和group指令添加到查询中),但它只是产生一条错误消息(-2147217904,缺少参数)。

我怀疑我需要某种JOIN,但这显然超出了我对SQL的了解。 有什么帮助吗?

[编辑]
像这样的事情就可以了(请参见SumGrouped字段):

Txt1   Txt2   Txt3   Bool1   Bool2   Bool3   Sum Amt1   Sum Amt2     SumGrouped
    A     B     F     NO     YES     NO       2               2900     21350
    A     B     F     NO     YES     YES      4               1000     21350
    A     B     F     YES    YES     NO       8               12700    21350
    A     B     F     YES    YES     YES      15              4750     21350
    A     B     G     NO     NO      YES      6               5150     6350
    A     B     G     NO     YES     NO       10              1200     6350
    A     B     H     NO     YES     YES      15              4150     4150
    A     B     I     YES    YES     NO       30              500      600
    A     B     I     YES    YES     YES      2               100      600
    A     B     J     YES    YES     YES      10              600      600
    A     D     F     NO     YES     YES      5               3900     11900
    A     D     F     YES    YES     NO       7               7800     11900
    A     D     F     YES    YES     YES      20              200      11900
    A     D     H     NO     NO      YES      8               5400     6700
    A     D     H     NO     YES     NO       5               1300     6700
    A     D     K     YES    YES     YES      6               800      800         

是的,现在我想知道使用数据透视表是否更容易

只需将两个查询加入主外部查询即可。 具体来说,将您的两个聚合查询(其中DISTINCTROW是多余的)用作派生表(即FROMJOIN子句中的子查询),然后将它们JOIN到文本字段上。

SELECT allagg.*, textagg.[Sum Amt2] AS SumGrouped
FROM
  (SELECT [Txt1], [Txt2], [Txt3], [Bool1], [Bool2], [Bool3],
          Sum([Amt1]) AS [Sum  Amt1], Sum([Amt2]) AS [Sum Amt2] 
   FROM [mytable] 
   GROUP BY [Txt1], [Txt2], [Txt3], [Bool1], [Bool2], [Bool3]) As allagg

INNER JOIN      
  (SELECT [Txt1], [Txt2], [Txt3],
          Sum([Amt1]) AS [Sum Amt1], Sum([Amt2])  AS [Sum Amt2] 
   FROM [mytable] 
   GROUP BY [Txt1], [Txt2], [Txt3]) As textagg

ON allagg.[Txt1] = textagg.[Txt1]
AND allagg.[Txt2] = textagg.[Txt2]
AND allagg.[Txt3] = textagg.[Txt3]

您可以将boolagg添加为第三个派生表。 而且,如果在MS Excel中运行SQL,您将使用Jet / ACE SQL方言,该方言要求在JOIN子句中的括号内包含两个以上的表。

SELECT allagg.*, textagg.[Sum Amt2] AS SumTxtGrouped, boolagg.[Sum Amt2] AS SumBoolGrouped
FROM
  ((SELECT [Txt1], [Txt2], [Txt3], [Bool1], [Bool2], [Bool3],
          Sum([Amt1]) AS [Sum  Amt1], Sum([Amt2]) AS [Sum Amt2] 
   FROM [mytable] 
   GROUP BY [Txt1], [Txt2], [Txt3], [Bool1], [Bool2], [Bool3]) As allagg

INNER JOIN      
  (SELECT [Txt1], [Txt2], [Txt3],
          Sum([Amt1]) AS [Sum Amt1], Sum([Amt2])  AS [Sum Amt2] 
   FROM [mytable] 
   GROUP BY [Txt1], [Txt2], [Txt3]) As textgg

ON allagg.[Txt1] = textagg.[Txt1]
AND allagg.[Txt2] = textagg.[Txt2]
AND allagg.[Txt3] = textagg.[Txt3])

INNER JOIN      
  (SELECT [Bool1], [Bool2], [Bool3],
          Sum([Amt1]) AS [Sum Amt1], Sum([Amt2])  AS [Sum Amt2] 
   FROM [mytable] 
   GROUP BY [Bool1], [Bool2], [Bool3]) As boolagg

ON allagg.[Bool1] = boolagg.[Bool1]
AND allagg.[Bool2] = boolagg.[Bool2]
AND allagg.[Bool3] = boolagg.[Bool3]

我会使用GROUP BY ROLLUP获得所需的结果。 GROUP BY ROLLUP各列周围的括号定义了您感兴趣的分组集。所有六个列中的最低详细信息组级别,仅3个txt列中的下一个最低详细信息组级别。 最后的最小粒度级别汇总了所有记录。

SQL小提琴

查询1

SELECT [Txt1], [Txt2], [Txt3]
     , [Bool1], [Bool2], [Bool3]
     , Sum([Amt1]) AS [Sum Amt1], Sum([Amt2]) AS [Sum Amt2] 
  FROM [mytable] 
 GROUP BY ROLLUP ( ([Txt1], [Txt2], [Txt3])
                 , ([Bool1], [Bool2], [Bool3]))
 ORDER BY grouping_id([txt1],[bool1])
     , [Txt1], [Txt2], [Txt3]
     , [Bool1], [Bool2], [Bool3]

结果

|   Txt1 |   Txt2 |   Txt3 |  Bool1 |  Bool2 |  Bool3 | Sum Amt1 | Sum Amt2 |
|--------|--------|--------|--------|--------|--------|----------|----------|
|      A |      B |      F |     NO |    YES |     NO |        2 |     2900 |
|      A |      B |      F |     NO |    YES |    YES |        4 |     1000 |
|      A |      B |      F |    YES |    YES |     NO |        8 |    12700 |
|      A |      B |      F |    YES |    YES |    YES |       15 |     4750 |
|      A |      B |      G |     NO |     NO |    YES |        6 |     5150 |
|      A |      B |      G |     NO |    YES |     NO |       10 |     1200 |
|      A |      B |      H |     NO |    YES |    YES |       15 |     4150 |
|      A |      B |      I |    YES |    YES |     NO |       30 |      500 |
|      A |      B |      I |    YES |    YES |    YES |        2 |      100 |
|      A |      B |      J |    YES |    YES |    YES |       10 |      600 |
|      A |      D |      F |     NO |    YES |    YES |        5 |     3900 |
|      A |      D |      F |    YES |    YES |     NO |        7 |     7800 |
|      A |      D |      F |    YES |    YES |    YES |       20 |      200 |
|      A |      D |      H |     NO |     NO |    YES |        8 |     5400 |
|      A |      D |      H |     NO |    YES |     NO |        5 |     1300 |
|      A |      D |      K |    YES |    YES |    YES |        6 |      800 |
|      A |      B |      F | (null) | (null) | (null) |       29 |    21350 |
|      A |      B |      G | (null) | (null) | (null) |       16 |     6350 |
|      A |      B |      H | (null) | (null) | (null) |       15 |     4150 |
|      A |      B |      I | (null) | (null) | (null) |       32 |      600 |
|      A |      B |      J | (null) | (null) | (null) |       10 |      600 |
|      A |      D |      F | (null) | (null) | (null) |       32 |    11900 |
|      A |      D |      H | (null) | (null) | (null) |       13 |     6700 |
|      A |      D |      K | (null) | (null) | (null) |        6 |      800 |
| (null) | (null) | (null) | (null) | (null) | (null) |      153 |    52450 |

查询2模拟的ROLLUP:

SELECT [Txt1], [Txt2], [Txt3]
     , [Bool1], [Bool2], [Bool3]
     , Sum([Amt1]) AS [Sum Amt1], Sum([Amt2]) AS [Sum Amt2] 
  FROM [mytable] 
 GROUP BY [Txt1], [Txt2], [Txt3]
        , [Bool1], [Bool2], [Bool3]
UNION ALL
SELECT [Txt1], [Txt2], [Txt3]
     , NULL, NULL, NULL
     , Sum([Amt1]) AS [Sum Amt1], Sum([Amt2]) AS [Sum Amt2] 
  FROM [mytable] 
 GROUP BY [Txt1], [Txt2], [Txt3]
UNION ALL
SELECT NULL, NULL, NULL
     , NULL, NULL, NULL
     , Sum([Amt1]) AS [Sum Amt1], Sum([Amt2]) AS [Sum Amt2] 
  FROM [mytable]

结果

|   Txt1 |   Txt2 |   Txt3 |  Bool1 |  Bool2 |  Bool3 | Sum Amt1 | Sum Amt2 |
|--------|--------|--------|--------|--------|--------|----------|----------|
|      A |      B |      F |     NO |    YES |     NO |        2 |     2900 |
|      A |      B |      F |     NO |    YES |    YES |        4 |     1000 |
|      A |      B |      F |    YES |    YES |     NO |        8 |    12700 |
|      A |      B |      F |    YES |    YES |    YES |       15 |     4750 |
|      A |      B |      G |     NO |     NO |    YES |        6 |     5150 |
|      A |      B |      G |     NO |    YES |     NO |       10 |     1200 |
|      A |      B |      H |     NO |    YES |    YES |       15 |     4150 |
|      A |      B |      I |    YES |    YES |     NO |       30 |      500 |
|      A |      B |      I |    YES |    YES |    YES |        2 |      100 |
|      A |      B |      J |    YES |    YES |    YES |       10 |      600 |
|      A |      D |      F |     NO |    YES |    YES |        5 |     3900 |
|      A |      D |      F |    YES |    YES |     NO |        7 |     7800 |
|      A |      D |      F |    YES |    YES |    YES |       20 |      200 |
|      A |      D |      H |     NO |     NO |    YES |        8 |     5400 |
|      A |      D |      H |     NO |    YES |     NO |        5 |     1300 |
|      A |      D |      K |    YES |    YES |    YES |        6 |      800 |
|      A |      B |      F | (null) | (null) | (null) |       29 |    21350 |
|      A |      B |      G | (null) | (null) | (null) |       16 |     6350 |
|      A |      B |      H | (null) | (null) | (null) |       15 |     4150 |
|      A |      B |      I | (null) | (null) | (null) |       32 |      600 |
|      A |      B |      J | (null) | (null) | (null) |       10 |      600 |
|      A |      D |      F | (null) | (null) | (null) |       32 |    11900 |
|      A |      D |      H | (null) | (null) | (null) |       13 |     6700 |
|      A |      D |      K | (null) | (null) | (null) |        6 |      800 |
| (null) | (null) | (null) | (null) | (null) | (null) |      153 |    52450 |

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM