Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将SQL结果分为两个子级别_Sql_Ms Access_Vba - Fatal编程技术网

将SQL结果分为两个子级别

将SQL结果分为两个子级别,sql,ms-access,vba,Sql,Ms Access,Vba,我正在使用Access前端屏幕和后端的SQL查询。我试图得到一个结果集,它分为两个级别:区域和月份,然后是该期间活动的客户总数的相关计数,有订单的客户和没有订单的客户都在用户选择的期间内 下面是正在使用的两个表 客户表A 订单表B 用户选择报告的开始日期和结束日期,例如2016年5月1日至2016年7月31日 我需要一个查询,该查询将评估客户开始日期是否在报告期内,并生成以下输出: 结果集 这件事我已经坚持了两个星期了。。请帮忙 如果有帮助的话,这就是我已经走了多远 PARAMETERS

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

下面是正在使用的两个表

客户表A

订单表B

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

结果集

这件事我已经坚持了两个星期了。。请帮忙

如果有帮助的话,这就是我已经走了多远

    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];

您可以使用join语句来检查日期,也可以使用BETWEEN操作。这里是示例和示例的链接

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

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,我看到一个客户在5月份有订单,另一个客户在7月份有订单,客户3


这种方法对您有用吗?

连接是最基本的。在将3个不同的参数分为2个级别时,如何计算它们的数量。是否要添加三个参数?您可以使用类似这样的方法从表组中选择q1、sumq2、sumq3、sumq4、sumq2+sumq3+sumq4作为q5。我也尝试了求和函数,它给出了相同的结果集。是的,结果集可能不正确,因为我是手动执行的。让我试试这个方法,看看是否达到预期效果。无论如何谢谢你!!我想我理解你的逻辑,感觉它越来越接近我所需要的。现在的挑战是我的clientID是字母数字的,所以Max无法工作。我如何确保即使在同一个月内有多个订单,也只对客户进行一次计数?啊,我刚刚意识到最大值用于计算1。。我的错。。我会再复习一遍。我曾在生产数据库中尝试过这种方法,但不幸的是,由于连接的性质,这给了我一个数以百万计的结果集。我尝试使用diff-join类型,结果是不正确的。我们有大约10000个客户,每个月订购5-6次。还有其他建议吗?您可以尝试将选择行标题区域、月份的逻辑提取到单独的查询或表中。您还可以简化我的示例,只在客户和月份之间交叉连接,然后将连接留给订单。如果性能仍然是一个问题,也许其他人会有更好的建议。
    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
    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];
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