从另一个表拉出条件更新 - 访问语法错误

时间:2015-04-23 16:07:48

标签: sql ms-access ms-access-2010

我是MS Access的初学者。

我有两张桌子 - workrelationship 给每个人为组织工作的日期(我们显然终止并重新雇用了很多),而 workterms 给出了开始/停止系统中每次为员工更改某些内容的日期 - 新地址,名称更改等。因此, workrelationship 期间可能有多个 workterms 期间。

workrelationship 中有一个 POS 列(服务期限ID),我需要将每个wt日期范围内的 workterms 复制到 workterms wr 日期范围内。然后我需要删除 workterms 中的每一行,其中日期不属于 wr 范围。

workterms 中有大约50k行,我需要这样做,所以我在Access中设置了样本表来玩。 Here's a link到两个表和错误消息(见下文)。

我的计划是首先拉入POS并标记任何不受工作关系日期“删除”限制的内容。然后我可以在 POS 列中显示“删除”的每一行上执行删除操作。 (DELETE FROM workterms WHERE pos = 'delete';

当我做第一部分时,我得到syntax error in Access

UPDATE workterms
SET wt.pos =
    CASE WHEN (wt.termstart >= wr.originalstart 
    and wt.termend <= wr.finalend) 
    THEN wr.pos
    ELSE 'delete' 
    END
FROM workterms wt
INNER JOIN workrelationship wr
ON wr.personid = wt.personid

关于语法错误的任何想法?它在第3行突出显示“WHEN”这个词。我不熟悉Access,但我一直在寻找,与我发现的相比,这看起来很正确。

编辑:我也试过IIF

UPDATE workterms
SET wt.pos =
    IIF ((wt.termstart >= wr.originalstart 
    and wt.termend <= wr.finalend), wr.pos, 'delete')
FROM workterms wt
INNER JOIN workrelationship wr
ON wr.personid = wt.personid;
编辑2:HansUp在下面的查询运行得很好(谢谢!!),它解决了语法问题。

UPDATE workterms wt
    INNER JOIN workrelationship wr
    ON wr.personid = wt.personid
SET wt.pos =
    IIF(
        wt.termstart >= wr.originalstart AND wt.termend <= wr.finalend,
        wr.pos,
        'delete'
        );

编辑3:但是 - it only brought 3 values in,我期待8,正如您在下面的选择和链接电子表格中的“从编辑3选择”选项卡中看到的那样:

SELECT wr.*, wt.*
FROM workrelationship wr, workterms wt
WHERE wr.personid = wt.personid 
and wt.termstart >= wr.originalstart 
and wt.termend <= wr.finalend

1 个答案:

答案 0 :(得分:1)

您当前的UPDATE查询未提供您想要的结果,因为INNER JOIN仅在[personid]上完成。因此,对于在[workrelationship]中出现多次的[personid],您的UPDATE查询会产生多个冲突的结果。

考虑以下SELECT查询,它模仿[personid] = 2的UPDATE查询的行为:

SELECT 
    IIF(
        wt.termstart >= wr.originalstart AND wt.termend <= wr.finalend,
        wr.pos,
        'delete'
        ) AS result,
    wt.personid,
    wt.termstart,
    wt.termend,
    wt.pos AS wt_pos,
    wr.originalstart,
    wr.finalend,
    wr.pos AS wr_pos
FROM 
    workterms wt
    INNER JOIN 
    workrelationship wr
        ON wr.personid = wt.personid 
WHERE wt.personid = 2
ORDER BY wt.termstart, wr.originalstart

结果

result  personid  termstart   termend     wt_pos  originalstart  finalend    wr_pos
------  --------  ----------  ----------  ------  -------------  ----------  ------
200-1          2  2010-02-01  2010-03-01  blah    2010-02-01     2010-05-01  200-1 
delete         2  2010-02-01  2010-03-01  blah    2010-07-01     2010-10-01  200-2 
200-1          2  2010-03-01  2010-05-01  blah    2010-02-01     2010-05-01  200-1 
delete         2  2010-03-01  2010-05-01  blah    2010-07-01     2010-10-01  200-2 
delete         2  2010-07-01  2010-10-01  blah    2010-02-01     2010-05-01  200-1 
200-2          2  2010-07-01  2010-10-01  blah    2010-07-01     2010-10-01  200-2 

请注意,每个[workterms]行出现两次,[workrelationship]中每个对应的行出现一次,[result]根据连接的[workrelationship]行而不同。因此,您的UPDATE查询实际上会更新每个[workterms]行两次。 wt.pos的最终值将是最后应用的值,并且应用更新的顺序完全取决于查询优化器。

所以你需要做的是两次通过应用更新。首先将所有wt.pos值设置为&#39; delete&#39;

UPDATE workterms SET pos = 'delete'

然后使用连接[personid]值日期的查询来更新要保留的八(8)行的wt.pos值:

UPDATE 
    workterms wt
    INNER JOIN 
    workrelationship wr
        ON wr.personid = wt.personid 
            AND wt.termstart >= wr.originalstart 
            AND wt.termend  <= wr.finalend
SET wt.pos = wr.pos

现在你的[workterms]表格如下所示:

personid  termstart   termend     pos   
--------  ----------  ----------  ------
       1  2010-08-01  2010-09-01  100-1 
       1  2010-03-01  2010-05-01  100-1 
       2  2010-07-01  2010-10-01  200-2 
       2  2010-03-01  2010-05-01  200-1 
       2  2010-02-01  2010-03-01  200-1 
       3  2010-11-01  2015-12-01  delete
       3  2010-09-01  2010-10-01  300-2 
       3  2010-08-01  2010-09-01  300-2 
       3  2010-07-05  2010-07-15  delete
       3  2010-05-01  2010-07-01  300-1