差距和岛屿 - Microsoft Access

时间:2017-12-06 14:17:55

标签: sql ms-access gaps-and-islands

我正在尝试按以下方式对数据进行分组:状态,产品,版本,LG_SG,区域和面积因素。然后,我想将最小开始日期和最长结束日期附加到记录中。我有一个差距和岛屿问题。如果查看数据,.8428会显示两个不按时间顺序排列的块。如何在Access中解决此问题?

这是我目前的数据。

state   start_date  end_date    product edition lg_sg   area    area_factor
IL  10/1/2010   11/1/2010   PPO 6   SG  1   0.86
IL  11/1/2010   12/1/2010   PPO 6   SG  1   0.86
IL  12/1/2010   1/1/2011    PPO 6   SG  1   0.86
IL  1/1/2011    2/1/2011    PPO 6   SG  1   0.8428
IL  2/1/2011    3/1/2011    PPO 6   SG  1   0.8428
IL  3/1/2011    4/1/2011    PPO 6   SG  1   0.8428
IL  4/1/2011    5/1/2011    PPO 6   SG  1   0.8428
IL  5/1/2011    6/1/2011    PPO 6   SG  1   0.8428
IL  6/1/2011    7/1/2011    PPO 6   SG  1   0.8428
IL  7/1/2011    8/1/2011    PPO 6   SG  1   0.8428
IL  8/1/2011    9/1/2011    PPO 6   SG  1   0.8428
IL  9/1/2011    10/1/2011   PPO 6   SG  1   0.8428
IL  10/1/2011   11/1/2011   PPO 6   SG  1   0.825944
IL  11/1/2011   12/1/2011   PPO 6   SG  1   0.825944
IL  12/1/2011   1/1/2012    PPO 6   SG  1   0.825944
IL  1/1/2012    2/1/2012    PPO 6   SG  1   0.8428
IL  2/1/2012    3/1/2012    PPO 6   SG  1   0.8428
IL  3/1/2012    4/1/2012    PPO 6   SG  1   0.8428
IL  4/1/2012    5/1/2012    PPO 6   SG  1   0.8428

我希望它看起来像这样。

state   start_date  end_date    product edition lg_sg   area    area_factor
IL  10/1/2010   1/1/2011    PPO 6   SG  1   0.86
IL  1/1/2011    10/1/2011   PPO 6   SG  1   0.8428
IL  10/1/2011   1/1/2012    PPO 6   SG  1   0.825944
IL  1/1/2012    5/1/2012    PPO 6   SG  1   0.8428

谢谢大家的帮助。

2 个答案:

答案 0 :(得分:0)

此代码是一个开始

SELECT data.state, data.start_date, data.product, data.edition, data.lg_sg, data.area, data.area_factor, data_1.area_factor AS previous
FROM data LEFT JOIN data AS data_1 ON data.start_date = data_1.end_date
WHERE (((data_1.area_factor) Is Null Or (data_1.area_factor)<>[data].[area_factor]));

它为您提供每个范围的开始日期,但不是结束日期。如果您将此作为参考来搜索特定日期,则可能就足够了 - 您可以搜索小于或等于搜索日期的最后一条记录,而无需结束日期。

我最初认为自动编号字段可以帮助识别结束日期,但现在我不确定。这个查询已经完成了我在自动编号字段中所做的工作,而且我还没有看到如何获得结束日期。

更新:这不是优雅,但我可以通过几个步骤完成: 将上面的查询保存为StartDates。然后使用此查询查找相同area_factors的下一个开始日期:

SELECT StartDates.state, StartDates.start_date, StartDates.product, StartDates.edition, StartDates.lg_sg, StartDates.area, StartDates.area_factor, (select min(start_date) from StartDates T where T.area_factor=StartDates.area_factor and T.start_date>StartDates.start_date) AS [Next]
FROM StartDates
ORDER BY StartDates.start_date;

将其保存为NextDates,然后使用此最终查询来获得答案:

SELECT NextDates.state, NextDates.start_date, Max(data.end_date) AS end_date, NextDates.product, NextDates.edition, NextDates.lg_sg, NextDates.area, NextDates.area_factor
    FROM NextDates INNER JOIN data ON NextDates.area_factor = data.area_factor
    WHERE (((data.start_date)<[next])) OR (((NextDates.Next) Is Null))
    GROUP BY NextDates.state, NextDates.start_date, NextDates.product, NextDates.edition, NextDates.lg_sg, NextDates.area, NextDates.area_factor;

根据数据的不同,您需要添加连接以将逻辑限制为匹配状态,产品或其他字段。

答案 1 :(得分:0)

考虑使用autonumber id字段(假设存在一个)创建不同的组 grp ,然后在外部查询中聚合:

SELECT r.state, Min(r.start_date) as min_start_date, Max(r.end_date) as 
       max_end_date, r.product, r.edition, r.lg_sg, Max(r.area) as max_area, 
       r.area_factor
FROM
  (SELECT *,
            (SELECT max(id) FROM GapsIslandsTable sub 
             WHERE sub.area_factor = g.area_factor 
               AND Year(sub.start_date) = Year(g.start_date)) as grp
   FROM GapsIslandsTable g) r

GROUP BY r.state, r.product, r.edition, r.lg_sg, r.area_factor, r.grp

-- state    min_start_date  max_end_date    product edition lg_sg   max_area   area_factor
-- IL            10/1/2011      1/1/2012        PPO       6    SG          1      0.825944 
-- IL             1/1/2011     10/1/2011        PPO       6    SG          1        0.8428 
-- IL             1/1/2012      5/1/2012        PPO       6    SG          1        0.8428 
-- IL            10/1/2010      1/1/2011        PPO       6    SG          1          0.86