SQL 选择结果:多表、自定义字段
Posted
技术标签:
【中文标题】SQL 选择结果:多表、自定义字段【英文标题】:SQL select results: multiple tables, custom fields 【发布时间】:2021-12-18 00:55:32 【问题描述】:我正在尝试从一个表中获取数据,同时删除另一个表中存在的信息。但是,我还添加了第三个表,并且我希望在输出中看到每个表的不同列名和数据。
例如,我有这样的数据:
表 1:成员 m
列:m.ID、m.cancelled_on
表 2:MEMBER_CATEGORY mc
列:mc.ID、mc.activity、mc.activity_date
表 3:MEMBER_CONTACT_SUPPRESSIONS mcs
列:mcs.ID、mcs.mailing_suppression、mcs.valid_to
我想通过过滤 m.cancelled_on IS NULL 来获取所有活跃成员。
然后我想从这些活跃成员中找到在特定日期范围内参与特定活动的成员。例如,在 2020 年 12 月 1 日和 2021 年 10 月 1 日之间“划船”。
我想根据这些数据集联系这些人。因此,我需要删除所有具有特定邮件抑制(例如,请勿联系)的人,该邮件抑制在比昨天晚的任何日期都有效。
关系说明:m.ID = mc.ID = mcs.ID
示例数据:
表 1:成员 m
m.ID | m.cancelled_on |
---|---|
1 | NULL |
2 | NULL |
3 | NULL |
4 | NULL |
5 | NULL |
6 | 2020-12-10 |
表 2:MEMBER_CATEGORY mc
mc.ID | mc.activity | mc.activity_date |
---|---|---|
1 | rowing | 2020-12-20 |
1 | rowing | 2020-12-20 |
2 | rowing | 2021-08-20 |
3 | rowing | 2021-05-25 |
4 | rowing | 2019-12-20 |
5 | cycling | 2020-10-10 |
6 | rowing | 2020-12-10 |
表 3:MEMBER_CONTACT_SUPPRESSIONS mcs
mcs.ID | mcs.mailing_suppression | mcs.valid_to |
---|---|---|
1 | NULL | NULL |
2 | DO NOT SMS | 2121-05-25 |
2 | DO NOT CONTACT | 2021-05-25 |
3 | DO NOT CONTACT | 2121-05-25 |
4 | NULL | NULL |
5 | DO NOT CONTACT | 2020-09-10 |
6 | NULL | NULL |
所以我将使用上面的示例应用的标准:
m.cancelled_on IS NULL, AND
mc.activity = 'rowing', AND
mc.activity_date BETWEEN '2020-12-01' AND '2021-10-01'
现在从结果数据中删除以下内容:
mcs.mailing_suppression IN ('DO NOT CONTACT','DO NOT TELEPHONE','DO NOT EMAIL'),
AND mcs.valid_to >= 2021-11-02)
然后我需要正确的结果显示如下:
m.ID | m.cancelled_on | mc.activity | mc.activity_date | mcs.mailing_suppression | mcs.valid_to |
---|---|---|---|---|---|
1 | NULL | rowing | 2020-12-20 | NULL | NULL |
2 | NULL | rowing | 2021-08-20 | DO NOT CONTACT | 2021-05-25 |
我已经尝试了各种 JOIN、EXCEPT、INTERSECT 组合,但我似乎无法得到它,所以现在非常感谢任何帮助!
提前致谢
【问题讨论】:
感谢@Michael 的所有帮助。 【参考方案1】:一切似乎都非常简单,所以我猜您在如何排除“请勿联系”成员方面遇到了麻烦。您可以使用NOT EXISTS
来完成此操作:
编辑:根据 cmets 更新答案。
select distinct m.id, mc.activity, mc.activity_date
from members as m
inner join member_category as mc
on m.id = mc.id
inner join member_contact_suppressions as mcs
on m.id = mcs.id
where m.cancelled_on is null
and mc.activity = 'rowing'
and mc.activity_date between '2020-12-01' and '2021-10-01'
and not exists (
select *
from member_contact_suppressions as mcs1
where mcs1.id = m.id
and mcs1.mailing_suppression in ('DO NOT CONTACT', 'DO NOT TELEPHONE', 'DO NOT EMAIL')
and mcs1.valid_to >= '2021-11-02'
)
where mcs1.id = m.id
是NOT EXISTS
中的子查询与外部查询结果集之间的“链接”。 NOT EXISTS
部分将排除那些满足子查询条件的成员。
db<>fiddle
【讨论】:
感谢@Michael 的所有帮助。但是,不幸的是,它仍然无法正常工作。这可能部分是我的错,因为我可能过度简化了一个更复杂的数据库。我已经运行了您的查询,它为我提供了 12603 行。如果我在 CARE NG CRM 系统中使用 List Manager 运行数据,我会得到 5127 - 我知道,这是正确的结果。您的查询结果仍然带有我希望删除的 mailing_suppression 条目。我认为这样做的原因是每个客户可以有多个 member_contact_suppressions 记录。 因此,它可能会获取所有 member_contact_suppressions 记录,包括我不想要的记录。我之前没有提到这一点完全是我的错。因此,这是否需要 DISTINCT 某处?再次感谢! 我的原始查询应该过滤掉任何有任何不联系记录的成员,但也许我误解了你的要求。您能否添加一些破坏查询的示例数据,以便我了解发生了什么? 嗨@Michael,我刚刚编辑了我的帖子以在抑制表中包含另一个条目。实际发生的事情(澄清我之前措辞不好的评论!)是结果包含该成员的所有 mailing_suppression 记录。我想对它们进行重复数据删除,因此每个 m.contact_number 只有一个条目 - 其余的似乎完全正确 - 谢谢!! (现在看到的结果是:1,NULL,rowing,2020-12-20,NULL,NULL / 2,NULL,rowing,2021-08-20,DO NOT SMS,2121-05-25 / 2,NULL,rowing, 2021-08-20,请勿联系,2021-05-25) 我想我遇到了一个问题,我试图将两条记录合二为一,但希望我能以某种方式做到这一点..??实际上,我不太关心显示抑制,只保留它以验证我的结果(我很高兴您在上面的查询正确完成了此操作)。我真正需要提供给联系人的是 m.ID 和 mc.activity_date,因此如果需要,可以从显示中删除其他字段。因此,每个单独的 m.ID 应该只有一个条目。我希望这是有道理的!以上是关于SQL 选择结果:多表、自定义字段的主要内容,如果未能解决你的问题,请参考以下文章