0

私がやっていること:

従業員が電子メールを処理するのに役立つ C# アプリケーションを作成しています。メールを含むデータベースがあります (MS SQL Server 2008 Express)。1 つのテーブルにはメール自体が含まれ (各行には msgId、送信者、受信者、件名、本文などの列があります)、もう 1 つのテーブルには、メールが従業員によってどのように処理されたかのデータが含まれます。メールにプロパティが割り当てられるたびに、新しい行プロパティとともに、2 番目のテーブルに保存されます。2 番目のテーブルには、列 msgId、forTeam、notForTeam、processedByTeam が含まれています。従業員が自分のチームに関連するメッセージをマークすると、forTeam 列に TEAMXX 値を持つ行が保存されます。従業員が電子メールに対して他のアクションを実行するたびに、TEAMXX 値を持つ行がprocessedByTeam 列に保存されます。

次の値を持つ電子メールを取得しようとして

ます

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')をテスト用に減らしても、何らかの理由でエラーが発生します。

私は何が欠けているか、間違っていますか?



アップデート:

(MailAssignments.notForTeam<>'TEAM01')どういうわけか問題を引き起こしているようです。他のすべては問題なく動作します (等号も問題ありません: MailAssignments.notForTeam='TEAM01') が、notForTeam<>条件を追加すると正しくない日時エラーが発生します (WTF? :/)

System.Data.SqlTypes.SqlTypeException: SqlDateTime オーバーフロー。1753 年 1 月 1 日 12:00:00 AM から 9999 年 12 月 31 日 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
4

2 に答える 2

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

SQL フィドルバージョン。

サンプル データとスキーマがあれば、世界は大きく変わります。MailAssignments見逃していたのは、各行に複数の行があることMailsです。したがって、 の行を除外すると言うとき、notForTeam = 'TEAM01'それが実際に意味することは、その値を持つ関連付けられた msgid をすべて除外することです。そのリクエストに対応するためにクエリを更新しました。ご想像のとおり、このExcept句は、最初のクエリに存在する 2 番目のクエリから一致する値を除外します。両方のクエリで定数を使用しているため、2 番目のクエリが指定された 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'
于 2012-05-12T16:28:45.523 に答える
0

試す:

WHERE
MailAssignments.forTeam='TEAM01'
AND MailAssignments.notForTeam<>'TEAM01'
AND MailAssignments.processedByTeam<>'TEAM01'
ORDER BY Mails.sortingTime DESC

これでうまくいくはずです

于 2012-05-12T16:24:00.947 に答える