我有两张表EmailQueue
和ReportQueue
。 EmailQueue
包含所有需要发送的电子邮件,ReportQueue
包含所有需要生成的报告。 ReportQueue
有一列ReportStatus
,用于显示报告是否已准备就绪。 N
是新的,C
已完成并准备就绪。
虽然在我的C#应用程序中发送电子邮件之前,我很容易检查所有报告是否已准备好发送电子邮件,但我希望不必首先拉出所有行并检查报告是否已准备就绪。我想知道是否有任何方式使用SQL只获取所有相应报告已准备好的电子邮件或没有报告的电子邮件?谢谢我对SQL比较陌生。
如果我通过C#这样做,我通常会做类似
的事情foreach (var email in emails)
{
if (reports.Where(x => x.EmailQueueId == email.EmailQueueId).All(x => x.ReportStatus == "C") ||
reports.Where(x => x.EmailQueueId == email.EmailQueueId) == null)
{
//Send Email out
}
}
数据库示例结构:
ReportQueue
+--------------+--------------------------------+--------------+
| EmailQueueId | ReportPath | ReportStatus |
+--------------+--------------------------------+--------------+
| 1 | null | N |
| 1 | C:\reports\report.xls | C |
| 3 | C:\reports\reportForThings.xls | C |
+--------------+--------------------------------+--------------+
EmailQueue
+--------------+-------------+
| EmailQueueId | EmailStatus |
+--------------+-------------+
| 1 | N |
| 2 | N |
| 3 | N |
+--------------+-------------+
在上面的示例中,电子邮件ID 2和3已准备好发送,但1不是因为其中一个报告尚未生成。
编辑:期望的结果可能只是一张准备好发送的电子邮件表,所以基于上面的例子,返回的表将是
+--------------+-------------+
| EmailQueueId | EmailStatus |
+--------------+-------------+
| 2 | N |
| 3 | N |
+--------------+-------------+
答案 0 :(得分:2)
SELECT Email.*
FROM EmailQueue As Email
LEFT JOIN (SELECT EmailQueueId,SUM(RStatus) As Tt
FROM (SELECT EmailQueueId,
CASE
WHEN reportStatus = 'N' THEN 0
WHEN reportStatus = 'C' THEN NULL
END As RStatus
FROM ReportQueue
) A
GROUP BY EmailQueueId
) AS Report ON(Email.EmailQueueId = Report.EmailQueueId)
WHERE Report.Tt IS NULL
答案 1 :(得分:1)
SELECT e.EmailQueueId, e.EmailStatus
FROM EmailQueue e
LEFT JOIN ReportQueue r ON e.EmailQueueId = r.EmailQueueId
GROUP BY e.EmailQueueId, e.EmailStatus
HAVING SUM(CASE WHEN r.ReportStatus IS NOT NULL AND
r.ReportStatus <> 'C'
THEN 1 ELSE 0 END) = 0 ;
这是 SQL Fiddle演示。
第二个选项:
SELECT e.*
FROM EmailQueue e
LEFT JOIN (SELECT COUNT(ReportStatus) num, EmailQueueId
FROM ReportQueue
WHERE ReportStatus <> 'C'
GROUP BY EmailQueueId) tr
ON e.EmailQueueId = tr.EmailQueueId
WHERE COALESCE(tr.num, 0) = 0;
第二个选项