根据MS Access中的开始日期和结束日期计算每周的客户端数

时间:2017-12-29 09:51:26

标签: sql database ms-access group-by

在MS Access DB中,我有关于客户的到达和离开日期的信息。基于此,我想计算每周访问的客户数量。

考虑以下示例。彼得在1月的第一周到达并在第三周离开(周日从周日开始)。另一方面,玛丽在第一周到达并离开。

enter image description here

我希望输出如下所示,第一列中的周数和第二列中的总访客数。

enter image description here

实现这一目标的最佳方式是什么?

3 个答案:

答案 0 :(得分:0)

我的解决方案采用德国日期格式,使用ORACLE进行测试。我每周都会建立一些日历表(tw_test_week)来加入它。

CREATE TABLE tw_test_client (
 client VARCHAR2(10),
 arrival DATE,
 departure DATE
);

INSERT INTO tw_test_client VALUES
( 'Peter', to_date('01.01.2018','DD.MM.YYYY'), to_date('11.01.2018','DD.MM.YYYY'));

INSERT INTO tw_test_client VALUES
( 'Mary', to_date('01.01.2018','DD.MM.YYYY'), to_date('01.02.2018','DD.MM.YYYY'));

CREATE TABLE tw_test_week (
 weekid INT,
 started DATE,
 ended DATE
);

INSERT INTO tw_test_week VALUES
( to_char(to_date('01.01.2018','DD.MM.YYYY'),'WW'),
  to_date('01.01.2018','DD.MM.YYYY'), 
  to_date('07.01.2018','DD.MM.YYYY')
);

INSERT INTO tw_test_week VALUES
( to_char(to_date('08.01.2018','DD.MM.YYYY'),'WW'),
  to_date('08.01.2018','DD.MM.YYYY'), 
  to_date('14.01.2018','DD.MM.YYYY')
);

INSERT INTO tw_test_week VALUES
( to_char(to_date('15.01.2018','DD.MM.YYYY'),'WW'),
  to_date('15.01.2018','DD.MM.YYYY'), 
  to_date('21.01.2018','DD.MM.YYYY')
);

INSERT INTO tw_test_week VALUES
( to_char(to_date('22.01.2018','DD.MM.YYYY'),'WW'),
  to_date('22.01.2018','DD.MM.YYYY'), 
  to_date('28.01.2018','DD.MM.YYYY')
);

INSERT INTO tw_test_week VALUES
( to_char(to_date('29.01.2018','DD.MM.YYYY'),'WW'),
  to_date('29.01.2018','DD.MM.YYYY'), 
  to_date('04.02.2018','DD.MM.YYYY')
);

SELECT w.weekid, COUNT(*) 
  FROM tw_test_week w
  JOIN tw_test_client c
    ON w.started BETWEEN c.arrival and c.departure
GROUP BY w.weekid
ORDER BY w.weekid;

结果

WEEKID  COUNT
1   2
2   2
3   1
4   1
5   1

答案 1 :(得分:0)

创建一个包含数字1到53的表。我的查询中的这个表名为WeekNumTable,包含一个列出每周编号的字段。

SELECT      WeekNum
            , COUNT(WeekNum) AS TotalClients
FROM        WeekNumTable INNER JOIN ClientTable ON 
                WeekNumTable.WeekNum>=DatePart("ww",ClientTable.Arrival-Weekday(ClientTable.Arrival,1)+7) AND
                WeekNumTable.WeekNum<=DatePart("ww",ClientTable.Departure-Weekday(ClientTable.Departure,1)+7)
GROUP BY    WeekNum  

您的示例让我感到困惑,因为您将第3周列为拥有1个客户端,而数据表则没有。

编辑:我可以看到的一个问题是,如果您确实想要查看接下来的100周,那么您将需要一些东西来分隔这些年份,否则第1周将从这两年开始被混为​​一谈。

答案 2 :(得分:0)

您可以使用一系列查询来获取此信息。

首先,创建一个名为 Ten 的查询:

SELECT DISTINCT Abs([id] Mod 10) AS N
FROM MSysObjects;

然后您可以创建一个查询 ClientDays ,列出您在首次到达和最近出发之间的所有日期:

SELECT DISTINCT 
    [Ten_0].[N]+[Ten_1].[N]*10+[Ten_2].[N]*100 AS Id, 
    DateAdd("d",[Ten_0].[N]+[Ten_1].[N]*10+[Ten_2].[N]*100,[StartDate]) AS [Date]
FROM 
    Ten AS Ten_0, 
    Ten AS Ten_1, 
    Ten AS Ten_2, 
    (Select 
        Min([Arrival]) As StartDate, 
        DateDiff("d", Min([Arrival]), Max([Departure])) As Days 
    From 
        ClientDates) AS T
WHERE 
    ((([Ten_0].[N]+[Ten_1].[N]*10+[Ten_2].[N]*100)<=[Days]) 
    AND 
    ((Ten_0.N)<=[Days]\1) 
    AND 
    ((Ten_1.N)<=[Days]\10) 
    AND 
    ((Ten_2.N)<=[Days]\100));

在查询 ClientWeeks 中使用此功能查找周数:

SELECT 
    Year([Date]) AS [Year], 
    DatePart("ww",[Date]) AS Week, 
    ClientDates.Client
FROM 
    ClientDays, 
    ClientDates
WHERE 
    ClientDays.Date Between [Arrival] And [Departure]
GROUP BY 
    Year([Date]), 
    DatePart("ww",[Date]), 
    ClientDates.Client;

最后,计算客户:

SELECT 
    ClientWeeks.Year, 
    ClientWeeks.Week, 
    Count(ClientWeeks.Client) AS TotalClients
FROM 
    ClientWeeks
GROUP BY 
    ClientWeeks.Year, 
    ClientWeeks.Week;

请注意,由于您打算使用不一致的周编号方法,因此您将难以计算新年。

唯一明确的周数是 yyyy-ww ISO-8601 系统,因为第一周和/或上周将跨越日历年界限。 / p>

如果您希望实现此功能,请留言,因为无法使用本机VBA功能;必须使用自定义函数,但如果您不使用它们,我不希望在此处发布它们。