我在做什么:
我正在编写一个C#应用程序,它将帮助员工处理电子邮件。我有一个带邮件的数据库(MS SQL Server 2008 Express)。一个表包含邮件本身(每行包含msgId,发件人,收件人,主题,正文等列),另一个表包含员工如何处理邮件的数据 - 每当电子邮件分配了一些属性时,新行将属性保存到第二个表。第二个表包含列:msgId,forTeam,notForTeam,processedByTeam。只要员工将消息标记为与其团队相关,就会在forTeam列中使用TEAMXX值保存一行。每当员工对电子邮件执行其他操作时,具有TEAMXX值的行将保存在processedByTeam列中。
我正在尝试收到以下值的电子邮件:
forTeam:'TEAM01'
notForTeam:与'TEAM01'不同的一切
processedByTeam:与'TEAM01'
我使用MailAssignments表在Mails表上进行LEFT JOIN,然后在WHERE之后我将上述条件放在上面。结果应该显示已分配给TEAM01但尚未由该团队的员工处理的消息。
问题:
我无法让SQL查询正常工作。条件的任何组合都将返回额外的行(例如,当我想省略那些时,属性为notForTeam ='TEAM01')或者由于某种原因给我一个错误,即datetime的格式不正确(我按接收时间排序电子邮件) )。
示例查询:
SELECT TOP 30 Mails.*
FROM Mails
LEFT JOIN MailAssignments
ON Mails.msgId = MailAssignments.msgId
WHERE
(MailAssignments.forTeam='TEAM01')
AND (MailAssignments.notForTeam<>'TEAM01' OR MailAssignments.notForTeam IS NULL)
AND (MailAssignments.processedByTeam<>'TEAM01' OR MailAssignments.processedByTeam IS NULL)
ORDER BY Mails.sortingTime DESC
即使我将WHERE之前(和ORDER BY之前)的条件减少到(MailAssignments.notForTeam<>'TEAM01')
进行测试,我仍然会因某种原因得到错误。
我错过了什么或做错了什么?
UPDATE:
似乎(MailAssignments.notForTeam<>'TEAM01')
以某种方式导致问题。其他一切正常(也是等号是OK:MailAssignments.notForTeam ='TEAM01')但是当我添加notForTeam<>
条件时,我得到了错误的日期时间错误(WTF?:/)
System.Data.SqlTypes.SqlTypeException:SqlDateTime溢出。必须在1/1/1753 12:00:00 AM和12/31/9999 11:59:59 PM之间。
更新 - 示例:
table with mails ("Mails"):
msgId sender subject body received (sortingTime)
53 x@x.com test test 2012-05-11 11:00
54 b@b.com test2 test2 2012-05-10 10:00
55 h@h.com blah blah 2012-05-11 12:00
56 t@t.com dfgg dfgg 2012-05-11 12:30
table with assignments ("MailAssignments"):
msgId forTeam notForTeam processedByTeam
54 null TEAM02 null - this means TEAM02 hid the mail from their view
54 TEAM01 null null - this means TEAM01 assigned the mail to them
54 null null TEAM01 - TEAM01 has processed the mail
53 TEAM01 null null - invisible to other teams
53 null TEAM01 null - invisible for TEAM01 (and also for others because of the above)
56 TEAM01 null null
56 null null TEAM01 - mail processed by TEAM01
55 TEAM02 null null - assigned to TEAM02 but not processed yet
Now, I want my C# app to have a view which will display mails as "This Team's", ie.:
1. mail 54 was first hidden for TEAM02 - should be invisible for them
2. mail 54 was assigned to TEAM01 - should be now visible for them in "This Team's" view
3. mail 54 was processed by TEAM01 - should be now invisible in "This Team's" view
4. mail 53 was assigned to TEAM01 - should visible in their "This Team's" view (and ONLY for them)
5. mail 53 was hidden for TEAM01 - should be invisible to TEAM01 (and for anyone else because of prev. action)
6. mail 56 was assigned to TEAM01 - should be now visible only to TEAM01 in "This Team's"
7. mail 56 was processed by TEAM01 - should be now invisible for TEAM01 in "This Team's"
So, with the present data in both tables, finally, TEAM02 for example should see in their "This Team's" view only:
mail 55
答案 0 :(得分:2)
Select TOP 30 *
From Mails As M
Where Exists (
Select 1
From MailAssignments As MA1
Where MA1.msgid = M.msgid
And MA1.forTeam = 'TEAM01'
Except
Select 1
From MailAssignments As MA1
Where MA1.msgid = M.msgid
And ( MA1.processedByTeam = 'TEAM01'
Or MA1.notForTeam = 'TEAM01' )
)
Order By M.received Desc
拥有样本数据和模式会让世界变得与众不同。错过的是每个MailAssignments
行有多个Mails
行。因此,当您说要排除notForTeam = 'TEAM01'
的行时,真正意味着排除任何具有该值的关联msgid。我已更新我的查询以适应该请求。您可能怀疑的Except
子句会消除第一个查询中存在的第二个查询中的任何匹配值。由于我在两个查询中都使用常量,如果第二个查询返回给定msgid的任何行,它将使整个Exists查询不返回任何行并排除msg。
也就是说,TEAM01
没有行,因为:
MsgId = 54 is excluded because according to Rule #3, messages
that were processed by the team should be excluded.
MsgId = 53 is excluded because notForTeam = 'TEAM01' (Rule #5)
MsgId = 56 is excluded because processedBy = 'TEAM01' (Rule #7)
MsgId = 55 is excluded because forTeam = 'TEAM02'
答案 1 :(得分:0)
尝试:
WHERE
MailAssignments.forTeam='TEAM01'
AND MailAssignments.notForTeam<>'TEAM01'
AND MailAssignments.processedByTeam<>'TEAM01'
ORDER BY Mails.sortingTime DESC
这应该可以解决问题