WHAT I’M DOING:
I’m writing a C# application which will help employees process emails. I have a database with mails (MS SQL Server 2008 Express). One table contains the mails themselves (each row has columns like msgId, sender, recipients, subject, body etc) and the other table contains data of how the mails have been processed by employees – whenever an email has some property assigned, a new row with the property is saved to the second table. The second table contains columns: msgId, forTeam, notForTeam, processedByTeam. Whenever an employee marks a message as related to his team, a row is saved with TEAMXX value in the forTeam column. Whenever an employee performs other actions on the email, a row with TEAMXX value is saved in the processedByTeam column.
I’m trying to get emails which have following values:
forTeam: ‘TEAM01’
notForTeam: everything different than ‘TEAM01’
processedByTeam: everything different than ‘TEAM01’
I do a LEFT JOIN on the Mails table with the MailAssignments table and then after WHERE I put the above conditions. The result is supposed to show messages which have been assigned to TEAM01 but have not been yet processed by the employees from this team.
THE PROBLEM:
I can’t get the SQL query to work properly. Any combination of the conditions will return extra rows (eg. with property notForTeam=’TEAM01′ when I want to omit those!) or give me an error that datetime is in incorrect format for some reason (I’m sorting emails by received time).
Example query:
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
Even if I reduce the conditions after WHERE (and before ORDER BY) to (MailAssignments.notForTeam<>'TEAM01') for testing, I still get the error for some reason.
What am I missing or doing wrong?
UPDATE:
It seems that (MailAssignments.notForTeam<>'TEAM01') is somehow causing the problem. Everything else works OK (also with the equals sign is OK: MailAssignments.notForTeam=’TEAM01′) but when I add the notForTeam<> condition I get the incorrect datetime error (WTF? :/)
System.Data.SqlTypes.SqlTypeException: SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.
UPDATE – EXAMPLE:
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
SQL Fiddle version.
Having the sample data and schema makes all the difference in the world. What was missed is that there are multiple
MailAssignmentsrows for eachMailsrow. So, when you say that you want to exclude rows wherenotForTeam = 'TEAM01', what that really means is to exclude any associated msgid that has that value. I’ve updated my query to accommodate that request. TheExceptclause as you might suspect eliminates any matching values from the second query that exist in the first query. Since I’m using a constant in both queries, if the second query returns any rows for the given msgid, it will make the entire Exists query return no rows and exclude the msg.That said, we get no rows for
TEAM01because: