从表中删除另一个表中不存在列的行

时间:2015-06-03 02:34:49

标签: sql sql-server sql-server-2008

我有这个SQL查询,如果他们没有登录30天(上次登录日期位于MOMUSER表中),则会从USERPREF表中删除用户的首选项,但是,它不会验证用户是否仍然存在在MOMUSER。我如何更改这一点,以便如果MOMUSER.CODE中不存在USERPREF.CUSER,那么USERPREF行也会在那种情况下被删除,因为它们没有上次登录日期?

    DELETE USERPREF FROM USERPREF
    INNER JOIN MOMUSER ON MOMUSER.CODE = USERPREF.CUSER
    WHERE MOMUSER.LOG_START < GETDATE()-30

4 个答案:

答案 0 :(得分:4)

更改为外部联接,撤消条件(以便匹配您想要保留的用户)并将其移至联接中,然后使用IS NULL删除行而不加入:

DELETE USERPREF
FROM USERPREF
LEFT JOIN MOMUSER ON MOMUSER.CODE = USERPREF.CUSER
    AND MOMUSER.LOG_START >= GETDATE()-30
WHERE MOMUSER.LOG_START IS NULL

回想一下,当连接未命中时,外连接返回所有空值。通过将日期条件移动到连接中,您可以练习它,但需要连接的行。 where子句过滤掉所有具有您想要保留的数据的行 - 只留下您想要删除的行。

答案 1 :(得分:0)

不是100%我理解您的问题,但我认为您可能正在寻找left join并检查是否MOMUSER.LOG IS NULL(如果它没有实际加入则应为null

DELETE USERPREF FROM USERPREF
LEFT JOIN MOMUSER ON MOMUSER.CODE = USERPREF.CUSER
WHERE MOMUSER.LOG_START < GETDATE()-30
OR MOMUSER.LOG_START IS NULL

答案 2 :(得分:0)

DELETE  FROM USERPREF u
 WHERE NOT EXISTS(SELECT NULL
                    FROM MOMUSER MOMUSER
                   WHERE MOMUSER.CODE = u.CUSER AND  MOMUSER.LOG_START < GETDATE()-30)

答案 3 :(得分:0)

这是Seth Answer的扩展,但在连接中使用cte.Remeber 子句会在加入前删除值

with cte
    as
    (
    select 
    *
    from USERPREF up
    left join
    MOMUSER  mu
    on 
    mu.CODE = up.CUSER
    and MOMUSER.LOG_START >= GETDATE()-30
    where MOMUSER.LOG_START IS NULL
    )
    ---select * from cte
    delete from cte