链式查询并从两个不同的表获取结果

问题描述 投票:0回答:1

我的 SQL Server 数据库中有两个表,我需要以相同的方式获取两个表的结果。我们有一个名为 tblEmail 的表和另一个名为 tblReply 的表。一切都从 tblEmail 表开始,每次我们的应用程序发送电子邮件时,我们都会在那里注册,当我们有外部回复时,它将在 tblReply 上。这样,tblEmail 将发送主电子邮件以及来自我的应用程序的所有回复。

还有另一个名为 tblOutgoing 的表,用于定义作为回复并链接到我们正在回复的外部回复的电子邮件。 (更改表结构不是一个选项)。

tbl电子邮件

邮箱ID 主题
1 发送的第一封电子邮件
2 从我的应用程序发送的第一个回复
3 从我的应用程序发送的第二个回复
4 从我的应用程序发送的第三条回复

tbl回复

电子邮件回复ID 邮箱ID 主题
1 1 第一个外部回复
2 2 第二次外部回复
3 3 第三次外部回复

tbl传出

邮箱ID 电子邮件回复ID
2 1
3 2
4 3

我需要的只是所有回复,发送的原始电子邮件不得在结果中(本例中EmailID = 1是原始电子邮件)。那么,如何使用原始电子邮件 ID 或任何电子邮件回复作为参数来获取结果?

我需要的结果:

邮箱ID 电子邮件回复ID 主题
1 第一个外部回复
2 从我的应用程序发送的第一个回复
2 第二次外部回复
3 从我的应用程序发送的第二个回复
3 第三次外部回复
4 从我的应用程序发送的第三条回复
sql sql-server t-sql
1个回答
0
投票

您的示例数据可能无法反映所有可能的情况,但对于您提供的内容,我有两种可能的解决方案。

假设 客户回复应用程序回复客户回复 之间存在(大部分)1:1 关系,您可以连接所有三个表并使用

CROSS APPLY(VALUES ...)
将结果拆分为单独的行。

SELECT V.EmailID, V.EmailReplyID, V.Subject
FROM tblReply R
LEFT JOIN tblOutgoing O ON O.EmailReplyID = R.EmailReplyID
LEFT JOIN tblEmail E ON E.EmailID = O.EmailID
CROSS APPLY (
    VALUES
        (1, CAST(NULL AS INT), R.EmailReplyID, R.Subject),
        (2, E.EmailID, CAST(NULL AS INT), E.Subject)
) V(Ordinal, EmailID, EmailReplyID, Subject)
ORDER BY R.EmailReplyID, V.Ordinal

如果关系不是 1:1,您可能需要

DISTINCT

另一种方法是编写两个单独的选择并使用

UNION ALL
组合结果。对结果进行排序有点棘手。下面将在内部查询中保留
EmailId
进行排序,然后在外部选择列表中过滤掉多余的值。

SELECT
    CASE WHEN U.EmailReplyID IS NULL THEN U.EmailId END AS EmailId,
    U.EmailReplyID,
    U.Subject
FROM (
    SELECT R.EmailID, R.EmailReplyID, R.Subject
    FROM tblReply R
    UNION ALL
    SELECT E.EmailID, CAST(NULL AS INT), E.Subject
    FROM tblOutgoing O
    JOIN tblEmail E ON E.EmailID = O.EmailID
) U
ORDER BY U.EmailID, U.EmailReplyID

上面使用

LEFT JOIN
来考虑客户回复尚未触发应用程序回复的可能性。

对于所提供的样本数据,两者的结果相同。

邮箱ID 电子邮件回复ID 主题
1 第一个外部回复
2 从我的应用程序发送的第一个回复
2 第二次外部回复
3 从我的应用程序发送的第二个回复
3 第三次外部回复
4 从我的应用程序发送的第三条回复

如果您的表有时间戳值,则可能会首选按这些值排序。

请参阅 this db<>fiddle 进行演示。

© www.soinside.com 2019 - 2024. All rights reserved.