sql - 如何使用 SQL 检索不在另一个列表中的结果列表
问题描述
我有一个规范化的 SQL 数据库。相关架构如下所示:
User
---
ID,
EmailAddress,
CategoryID
EmailLog
--------
ID,
CategoryID,
UserID,
SentOn
我需要获取今天尚未针对特定类别发送电子邮件的用户列表。根据我的理解,我需要执行一个LEFT JOIN
. 为了做到这一点,我尝试了以下方法:
DECLARE @Today AS DATETIME;
SET @Today = GETUTCDATE();
DECLARE @CategoryID AS INT;
SET @CategoryID = 101;
SELECT
User.ID,
User.EmailAddress,
FROM
(SELECT u.ID, u.EmailAddress, u.CategoryID FROM [dbo].[User] u WHERE u.CategoryID=@CategoryID) AS User
LEFT JOIN
(SELECT l.CategoryID l.SentOn FROM [dbo].[EmailLog] l WHERE l.CategoryID=@CategoryID AND DAY(l.SentOn)=DAY(@Today) AND MONTH(l.SentOn)=MONTH(@Today) AND YEAR(l.SentOn)=YEAR(@Today)) AS Log
ON User.UserID = Log.UserID
WHERE
Log.SentOn IS NULL
我在这个问题中使用子查询,因为我的实际查询更复杂。但是,我已经验证每个子查询都返回了我预期的结果。换句话说,第一个子查询返回一个User
列表。第二个子查询返回今天EmailLog
发送的电子邮件列表。
我被困在我检索今天尚未发送电子邮件的用户的部分。这就像我试图证明一个负面的。我错过了什么?
谢谢!
解决方案
使用Log.SentOn IS NULL
条件ON Clause
代替Where Clause
SELECT
User.ID,
User.EmailAddress,
FROM
(SELECT u.ID, u.EmailAddress, u.CategoryID FROM [dbo].[User] u WHERE u.CategoryID=@CategoryID) AS User
LEFT JOIN
(SELECT l.CategoryID l.SentOn FROM [dbo].[EmailLog] l WHERE l.CategoryID=@CategoryID AND DAY(l.SentOn)=DAY(@Today) AND MONTH(l.SentOn)=MONTH(@Today) AND YEAR(l.SentOn)=YEAR(@Today)) AS Log
ON User.UserID = Log.UserID and Log.SentOn IS NULL
推荐阅读
- flutter - 如何在颤动中解析列表映射Json到列表视图?
- python - 在 savgol_filter 中通过 Savitzky-Golay 滤波器使用差分平滑后得到原始平滑数据
- excel - 在 Excel 中创建和重命名工作表的方法(ws.title 与 wb.create_sheet)
- ios - 如何使用 Swift 使图像更小以适合 Mapbox 上的标记
- xamarin - 如何以编程方式获取主题颜色
- angularjs - 使用 angular-translate 的 angular-formly 验证消息翻译
- java - 如何将通用列表映射到另一个通用列表?
- javascript - JSX vs 组件引用作为值类型
- java - 构建jlink后如何检查文件是否存在?
- javascript - js单位换算