我有一个标准化的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
今天发送的电子邮件列表。
我被困在那一部分,我检索的用户尚未发送电子邮件今天虽然。就像我想证明一个否定的观点。我错过了什么?
谢谢您!
2条答案
按热度按时间f8rj6qna1#
我会用
not exists
:我不知道你为什么用utc日期。我希望本地日期/时间更有意义,但这是来自您的示例代码。
toe950272#
使用
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