Ms Access 按条件删除列中除一个值以外的所有值

MsAccess Delete all values but one in column by condition

我在 MS ACCESS 2013 中有一个 table,如下所示:

    Id        Department        Status           FollowingDept         ActualArea
  1000         Thinkerers       Thinking          Thinkerer             Thinkerer      
  1000         Drawers          OnDrawBoard       Drawers               Drawers
  1000         MaterialPlan     To Plan           MaterialPlan        MaterialPlan  
  1000         Painters         MatNeeded         MaterialPlan        
  1000         Builders         DrawsNeeded       Drawers             

table给follow一个ID,要经过五个部门,每个部门至少有5个不同的status。

每个状态都有一个 FollowingDept 值,例如 *Department* Thinkerers 具有状态 MoreCoffeeNow,这意味着 *FollowingDept* Drawers

除 ActualArea 之外的所有列都是从查询的提要中获取值的列。

ActualArea 是我插入此逻辑的 Expr:

Iif(FollowingDept = Department, FollowingDept, "") 

我的逻辑很简单,如果FollowingDept和Department重合,那么ID的ActualArea就取FollowingDept的值。

但是如您所见,在极少数情况下,ID 就像我上面的示例,其中 3 个部门与 FollowingDept 重合。这种情况很少见,但我想在 Access 中添加类似优先级的东西。

Thinkerers 具有最高优先级,然后是 MaterialPlan,然后是 Drawers,然后是 Builders,最后是 Painters。因此,按照相同的示例,在 ActualArea 获得 3 个值之后,Access 将执行另一个查询或子查询或其他任何内容,其中它将评估每个值的优先级并且只留下具有最​​高优先级的那个。因此在本例中,Thinkerers 获得最高优先级,其他两个值从 ActualArea 列中消除。

请记住,有超过 500 个不同的 ID,每个 ID 重复 5 次,因此要评估的记录总数为 2500。

您需要另一个 table,使用 actualArea 的可能值和优先级作为数字,然后您可以 select 使用 JOIN 并按优先级排序:

SELECT TOP 1 d.*, p.priority 
FROM departments d
LEFT JOIN priorities p ON d.actualArea = p.dept
WHERE d.id = 1000
AND p.priority IS NOT NULL
ORDER BY p.priority ASC

IS NOT NULL 子句消除了 actualArea 为空的所有行。 TOP 条件仅保留具有最高优先级的行。

您的 table 似乎没有主键。如果您不这样做,那么我会在一分钟内给出另一个查询,但我 强烈 建议您返回并向 table 添加主键。它会在以后为您省去大量令人头疼的事情。我确实在我的测试 table 中添加了这样一个密钥,它被称为 pID。此查询使用该 pID 来删除您需要的记录:

DELETE FROM departments WHERE pID NOT IN (

   SELECT TOP 1 d.pID
   FROM departments d
   LEFT JOIN priorities p ON d.actualArea = p.dept
   WHERE id = 1000
   AND p.priority IS NOT NULL
   ORDER BY p.priority ASC

)

如果您不能向数据添加主键并且 actualArea 被假定为唯一的,那么您可以只使用actualArea 值来执行删除:

DELETE FROM departments WHERE actualArea NOT IN (

   SELECT TOP 1 d.actualArea
   FROM departments d
   LEFT JOIN priorities p ON d.actualArea = p.dept
   WHERE id = 1000
   AND p.priority IS NOT NULL
   ORDER BY p.priority ASC

) AND id = 1000

如果 actualArea 不是唯一的,那么我们需要重新审视这个答案。此答案还假定您已经拥有身份证号码。