将SQL结果分组为2个子级

时间:2016-08-10 01:30:32

标签: sql ms-access access-vba

我在后端使用Access前端屏幕和SQL查询。我试图得到一个分为2个级别的结果集:Region&月份,然后是该期间内活跃客户总数的相关数量,订单客户和没有订单的客户都在用户选择的期间内。

以下是正在使用的2个表

客户表A

    ID   |  Region   |  StartDate  |   Name
     1   |  North    |   1 Jan 16  |   ABC
     2   |  North    |   1 Mar 16  |   DEF
     3   |  East     |   1 Jul 16  |   GHE
     4   |  East     |   1 Aug 16  |   HIJ
     5   |  West     |   1 Feb 16  |   KLM
     6   |  West     |   1 Mar 16  |   NOP
     7   |  South    |   1 Apr 16  |   QUR
     8   |  South    |   1 Jan 16  |   STU

订单表B

    OrderID | Client ID   |Order Date
     1      |    1        | 15 Mar 16  
     2      |    3        | 15 Jul 16  
     3      |    5        | 15 Jun 16  
     4      |    8        | 15 Jul 16  
     5      |    6        | 15 Jul 16  
     6      |    4        | 15 Jan 16  
     7      |    2        | 15 Feb 16  
     8      |    1        | 15 Jul 16  
     9      |    3        | 05 Aug 16  
    10      |    3        | 16 Jul 16  
    11      |    2        | 15 May 16  
    12      |    4        | 15 May 16  
    13      |    6        | 15 May 16  
    14      |    7        | 15 Mar 16  

用户选择2016年5月1日至7月31日期间报告的开始日期和结束日期 我需要一个查询来评估客户开始日期是否在报告期内并产生以下输出:

结果集

    Region | Month  |Total Clients|Clients with Orders|Clients w/o Orders
    North  |May-2016|   2         |   1               |     1
    North  |Jun-2016|   2         |   0               |     2
    North  |Jul-2016|   2         |   1               |     1
    East   |May-2016|   0         |   0               |     0
    East   |Jun-2016|   0         |   0               |     0
    East   |Jul-2016|   1         |   1               |     0
    West   |May-2016|   2         |   1               |     1
    West   |Jun-2016|   2         |   0               |     2
    West   |Jul-2016|   2         |   1               |     1
    South  |May-2016|   2         |   0               |     2
    South  |Jun-2016|   2         |   0               |     2
    South  |Jul-2016|   2         |   1               |     1

我已经坚持了2周了..请帮助!!!

如果这有助于我走了多远

    PARAMETERS startDt DateTime, endDt DateTime, loc Text ( 255 );
    SELECT DISTINCT a.[Region] AS Region, 
    Format(b.[Orderdate],"MMM-YY") AS MonthOrder, 
    (Select Count(CMet.[clientID]) as cnt  from 
    (SELECT distinct b.[orderID], Format(b.[order date],"MMM-YY") 
    as Contact_Month, a.[clientID], a.[Region]
    FROM Client as a 
    INNER JOIN orders AS b ON a.[client ID] = b.[client id]
    WHERE iif(isnull(loc),a.[REgion] like '*',instr (loc,a.[region]))
    and (b.[orderdate] between startDt and endDt)  
    and (a.[Start date] < startDt) 
    GROUP BY a.[Region], Format(b.[order date],"MMM-YY"), 
    a.[clientID], a.[Region]
    HAVING count(a.[clientID]) >=1) as CMet) AS Clients_Met, 
    (select count([client id]) from clients where 
    iif(isnull(loc),[region] like '*',instr (loc,[region])) and 
    client.[Start date] < startDt AS Total_Client, 
    (Total_Client-Clients_Met) AS Not_Met, 
    format(Clients_Met/iif(Total_Client =0,1,Total_Client),'##.##%') AS Met_Percentage
    FROM clients AS a 
    INNER JOIN orders AS b ON a.[client ID]=b.[client id]
    WHERE iif(isnull(loc),a.[region] like '*',instr (loc,a.[region]))
    and (a.[Start date] < startDt 
    GROUP BY a.[region], Format(b.[order date],"MMM-YY")
    HAVING count(a.[client id]) >=1
    ORDER BY a.[region];

2 个答案:

答案 0 :(得分:2)

我尝试了以下解决方案。我们的想法是在内部查询中进行分组,然后在外部查询中进行求和:

SELECT Region, Month, Count(ID) AS Clients, Sum(HasOrder) AS ClientsWithOrders, 
    [Clients]-[ClientsWithOrders] AS ClientsWithoutOrders
FROM (SELECT Region, CDate(Month([Order Date]) & "/1/" & Year([Order Date])) AS [Month], 
      ID, Max(IIf([Client ID]=[ID],1,0)) AS HasOrder
      FROM Orders, Client
      WHERE ((([Order Date])>=#5/1/2016# And 
          ([Order Date])<DateAdd("d",1,#7/31/2016#)))
      GROUP BY Region, CDate(Month([Order Date]) & "/1/" & Year([Order Date])), ID) 
         AS RegionMonthClient
GROUP BY Region, Month

困难在于我得到了不同的结果。例如,对于东方客户(3,4),我看到一个订单在五月(客户4)和一个订单在七月(客户3)。

这种方法对你有用吗?

答案 1 :(得分:0)

您可以使用join语句并使用BETWEEN操作检查日期。以下是示例join statementBetween Opration的链接。