SQL:表包含单个项目和FK到列表 - 返回表格和表格中的所有单个项目列表

时间:2016-05-06 19:25:13

标签: sql .net sql-server vb.net sql-server-2012

我有一张表结合了:

  • 自动电子邮件的条件(FK到具有自动电子邮件UI操作触发器的表)
  • 个人用户的电子邮件(FK到电子邮件表)
  • 邮件列表(FK到带邮件列表的表格)

这张表允许我:

  • 将个别电子邮件添加到自动电子邮件触发器
  • 将个别电子邮件添加到邮件列表
  • 将邮件列表添加到自动电子邮件触发器
    • 邮件列表只有个人电子邮件 - 邮件列表不能嵌套

当我需要从网站发送电子邮件时,我需要为所需的自动电子邮件触发器提取所有不同的电子邮件。我想要个人电子邮件。对于分配给触发器的任何/所有邮件列表,我想返回该邮件列表的电子邮件,而不是邮件列表的名称。

编辑(更新表格):

实际数据库表:

用户表

User_ID   First_Name   Last_Name   Email        Other Info (multiple columns)
----------------------------------------------------------------------------
1         Mike         Smith       mike@me.com   <other info>
2         Sue          Jones       sue@me.com    <other info>
3         Bob          Roberts     bob@me.com    <other info>
4         Mary         Evans       mary@me.com   <other info>
5         Joe          Miller      joe@me.com    <other info>

Auto_Email表

Auto_Email_ID   Page      Trigger
----------------------------------------------------------------------------
1               Events    Save Event
2               Events    Edit Event
3               Events    Delete Event
4               Friends   Request Friend
5               Friends   Confirm Friend

Mailing_List表

Mailing_List_ID   Mailing_List
----------------------------------------------------------------------------
1                 Team A
2                 Team B
3                 Team C

Email_List表

ID   Auto_Email_ID   User_ID    List_ID
----------------------------------------------------------------------------
1    1               1          NULL
2    1               NULL       1
3    1               NULL       2
4    2               2          NULL
5    2               NULL       3
6    NULL            1          1
7    NULL            3          1
8    NULL            4          2
9    NULL            5          3

Email_List视图

ID   Auto_Email_ID   Trigger         User_ID   Email         List_ID   List
----------------------------------------------------------------------------
1    1               Save Event      1         mike@me.com   NULL      NULL
2    1               Save Event      NULL      NULL          1         Team A
3    1               Save Event      NULL      NULL          2         Team B
4    2               Confirm Friend  2         sue@me.com    NULL      NULL
5    2               Confirm Friend  NULL      NULL          3         Team C
6    NULL            NULL            1         mike@me.com   1         Team A
7    NULL            NULL            3         bob@me.com    1         Team A
8    NULL            NULL            4         mary@me.com   2         Team B
9    NULL            NULL            5         joe@me.com    3         Team C

Auto_Email条件“保存事件”的所需结果:(来自个人电子邮件,A队电子邮件和B队电子邮件):

mike@me.com
bob@me.com
mary@me.com

我知道如何使用下面的代码执行此操作,但这是很多循环并回调SQL。我更喜欢使用单个SQL proc / query执行此操作,但我不知道如何。

使用vb.Net:

Dim sendTo = New List(Of String)

For Each email As MyObject In GetEmailsForAutoEmail("Save Event") 'calls SQL proc
    If (email.Email_ID.HasValue) Then
        sendTo.Add(email.Email)
    Else
        For Each mlEmail As MyObject In GetEmailsForMailingList(email.List) 'calls SQL proc
            sendTo.Add(mlEmail.Email)
        Next
    End If
Next

sendTo = sendTo.Distinct()

1 个答案:

答案 0 :(得分:0)

以下似乎可以完成这项工作:

SELECT
  email
FROM Usr U
JOIN Email_List E
  ON U.user_ID = E.user_ID
  AND E.list_ID IS NULL
JOIN Auto_Email A
  ON E.auto_Email_ID = A.auto_Email_ID
  AND A.triggr = 'Save Event'
UNION
SELECT
  email
FROM Usr U
JOIN Email_List E1
  ON U.user_ID = E1.user_ID
  AND E1.auto_Email_ID IS NULL
JOIN Email_List E2
  ON E1.list_ID = E2.list_ID
  AND E1.auto_Email_ID IS NULL
  AND E2.user_ID IS NULL
JOIN Mailing_List M
  ON E2.list_ID = M.mailing_List_ID
  AND E2.user_ID IS NULL
JOIN Auto_Email A
  ON E2.auto_Email_ID = A.auto_Email_ID
  AND E2.user_ID IS NULL
  AND A.triggr = 'Save Event'
;

UNION与用户单独列出的用户,通过某些列表注册。

查看实际操作:SQL Fiddle

为了更简单的SQL /更好的可读性(以及可能稍微好一点的性能), Email_List 表可能最好分成两个或三个表:

  • User_List 匹配用户和列表,
  • 一个(每个)用户和列表与 Auto_Email 对齐。

如果需要调整/进一步详细说明,请发表评论。