我有这个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
答案 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