Rus*_*tte 3 sql join unique distinct
你们真是太棒了.在过去的几天里,我已经在这里发布了两次 - 一个新用户 - 我被帮助感到震惊.所以,我想我会在我的软件中查看最慢的查询,看看是否有人可以帮助我加快速度.我将此查询用作视图,因此快速(并且不是!)非常重要.
首先,我有一个存储我公司客户的联系人表.在表中是一个JobTitle列,其中包含在Contacts_Def_JobFunctions表中定义的ID.还有一个名为contacts_link_job_functions的表,其中包含contactID编号和客户具有的其他作业功能 - 也在Contacts_Def_JobFunctions表中定义.
其次,Contacts_Def_JobFunctions表记录与它们自己有父/子关系.通过这种方式,我们将类似的工作职能集中在一起(例如:女仆,洗衣服务,家务管理,清洁等等都是基本工作 - 而职称可能会有所不同).我们目前不使用的工作职能被保留为ParentJobID 1841的子女.
第三,使用zipcodes附加的机构只是为最终结果提供地理数据.
最后,与所有负责任的公司一样,我们为希望选择退出我们的新闻通讯(选择加入后)的任何客户提供删除列表.
我使用以下查询来构建一个表格,其中列出了那些选择接收我们的新闻通讯并且具有与我们提供的服务/产品相关的工作职能或职位的人员.
这是我的UGLY查询:
SELECT DISTINCT
dbo.contacts_link_emails.Email, dbo.contacts.ContactID, dbo.contacts.First AS ContactFirstName, dbo.contacts.Last AS ContactLastName, dbo.contacts.InstitutionID,
dbo.institutionswithzipcodesadditional.CountyID, dbo.institutionswithzipcodesadditional.StateID, dbo.institutionswithzipcodesadditional.DistrictID
FROM
dbo.contacts_def_jobfunctions AS contacts_def_jobfunctions_3
INNER JOIN
dbo.contacts
INNER JOIN
dbo.contacts_link_emails
ON dbo.contacts.ContactID = dbo.contacts_link_emails.ContactID
ON contacts_def_jobfunctions_3.JobID = dbo.contacts.JobTitle
INNER JOIN
dbo.institutionswithzipcodesadditional
ON dbo.contacts.InstitutionID = dbo.institutionswithzipcodesadditional.InstitutionID
LEFT OUTER JOIN
dbo.contacts_def_jobfunctions
INNER JOIN
dbo.contacts_link_jobfunctions
ON dbo.contacts_def_jobfunctions.JobID = dbo.contacts_link_jobfunctions.JobID
ON dbo.contacts.ContactID = dbo.contacts_link_jobfunctions.ContactID
WHERE
(dbo.contacts.JobTitle IN
(SELECT JobID
FROM dbo.contacts_def_jobfunctions AS contacts_def_jobfunctions_1
WHERE (ParentJobID <> '1841')))
AND
(dbo.contacts_link_emails.Email NOT IN
(SELECT EmailAddress
FROM dbo.newsletterremovelist))
OR
(dbo.contacts_link_jobfunctions.JobID IN
(SELECT JobID
FROM dbo.contacts_def_jobfunctions AS contacts_def_jobfunctions_2
WHERE (ParentJobID <> '1841')))
AND
(dbo.contacts_link_emails.Email NOT IN
(SELECT EmailAddress
FROM dbo.newsletterremovelist AS newsletterremovelist))
Run Code Online (Sandbox Code Playgroud)
我希望你们中的一些超级巨星可以帮我调整一下.
非常感谢,
拉塞尔舒特
UPDATE - UPDATE - UPDATE - UPDATE - UPDATE
在收到几条反馈消息后,特别是来自Khanzor,我努力调整此查询并提出以下建议:
SELECT DISTINCT
contacts_link_emails.Email, contacts.ContactID, contacts.First AS ContactFirstName, contacts.Last AS ContactLastName, contacts.InstitutionID,
institutionswithzipcodesadditional.CountyID, institutionswithzipcodesadditional.StateID, institutionswithzipcodesadditional.DistrictID
FROM contacts
INNER JOIN
contacts_def_jobfunctions ON contacts.jobtitle = contacts_def_jobfunctions.JobID AND contacts_def_jobfunctions.ParentJobID <> '1841'
INNER JOIN
contacts_link_jobfunctions ON contacts_link_jobfunctions.JobID = contacts_def_jobfunctions.JobID AND contacts_def_jobfunctions.ParentJobID <> '1841'
INNER JOIN
contacts_link_emails ON contacts.ContactID = contacts_link_emails.ContactID
INNER JOIN
institutionswithzipcodesadditional ON contacts.InstitutionID = institutionswithzipcodesadditional.InstitutionID
LEFT JOIN
newsletterremovelist ON newsletterremovelist.emailaddress = contacts_link_emails.email
WHERE
newsletterremovelist.emailaddress IS NULL
Run Code Online (Sandbox Code Playgroud)
这不是很完美(我怀疑我应该做一些外连接或右连接或其他东西,我不太确定).我的结果集大约是我原始查询提供的记录的40%(我不再100%肯定是一个完美的查询).
为了清理,我拿出了所有的"dbo".SQL Studio添加的前缀.他们做了什么吗?
我现在做错了什么?
谢谢,
拉塞尔舒特
== == == == == ==另一个更新==另一个更新==另一个更新==另一个更新==另一个更新== == == == ==
我已经在这个问题上工作了好几个小时了.我已经明白了:
SELECT DISTINCT
contacts_link_emails.Email, contacts.contactID, contacts.First AS ContactFirstName, contacts.Last AS ContactLastName, contacts.InstitutionID,
institutionswithzipcodesadditional.CountyID, institutionswithzipcodesadditional.StateID, institutionswithzipcodesadditional.DistrictID
FROM
contacts INNER JOIN institutionswithzipcodesadditional
ON contacts.InstitutionID = institutionswithzipcodesadditional.InstitutionID
INNER JOIN contacts_link_emails
ON contacts.ContactID = contacts_link_emails.ContactID
LEFT OUTER JOIN contacts_def_jobfunctions
ON contacts.JobTitle = contacts_def_jobfunctions.JobID AND contacts_def_jobfunctions.ParentJobID <> '1841'
LEFT OUTER JOIN contacts_link_jobfunctions
ON contacts_link_jobfunctions.JobID = contacts_def_jobfunctions.JobID AND contacts_def_jobfunctions.ParentJobID <> '1841'
LEFT OUTER JOIN
newsletterremovelist ON newsletterremovelist.EmailAddress = contacts_link_emails.Email
WHERE (newsletterremovelist.EmailAddress IS NULL)
Run Code Online (Sandbox Code Playgroud)
令人失望的是,我只是无法填补我的知识空白.我是新手加入的,除非我有可视化工具为我构建它们,所以我想我想要所有来自联系人,机构和zipcodesadditional以及contacts_link_emails,所以我已经INNER加入了他们(上图).
我对下一点感到难过.如果我INNER加入他们,那么我会找到有适当工作的人(<> 1841) - 但我想我会失去那些没有JobTitle和JobFunctions条目的人.在许多情况下,这是不对的.我可以有一个JobTitle"Custodian",我想留在我们的新闻通讯列表中,但如果他还没有JobFunction条目,我认为如果我使用INNER JOIN,他将不在列表中.
但是,如果我使用LEFT OUTER JOIN进行查询,如上所述,我认为我有很多人使用错误的JobTitles,只是因为任何缺少JobTitle或JobFunction的人都会出现在我的列表中 - 他们可能是"高级执行官"没有JobFunction,他们会在名单上 - 这是不对的.我们不再拥有适合"高级管理人员"的服务.
然后我看看LEFT OUTER JOIN如何为newsletterremovelist工作.这很光滑,我想我做得对...
但我仍然被卡住了.希望有人能看到我在这里想要做的事情,并引导我朝着正确的方向前进.
谢谢,
拉塞尔舒特
再次更新
可悲的是,这个线程似乎已经死了,没有一个完美的解决方案 - 但我已经接近了.请看一个重新开始讨论的新线程:点击这里
(为所提供的大量工作提供了正确的答案 - 即使没有达到正确的答案).
谢谢!
拉塞尔舒特
将您的查询移动WHERE到实际联接.这些被称为相关子查询,是Voldemort的工作.如果它们是连接,它们只执行一次,并且会加快查询速度.
对于NOT IN节,使用左外连接,并检查您加入的列是否NULL.
另外,尽可能避免OR在WHERE查询中使用 - 请记住,这OR不一定是短路操作.
一个例子如下:
SELECT
*
FROM
dbo.contacts AS c
INNER JOIN
dbo.contacts_def_jobfunctions AS jf
ON c.JobTitle = jf.JobId AND jf.ParentJobID <> '1841'
INNER JOIN
dbo.contacts_link_emails AS e
ON c.ContactID = e.ContactID AND jf.JobID = c.JobTitle
LEFT JOIN
dbo.newsletterremovelist AS rl
ON e.Email = rl.EmailAddress
WHERE
rl.EmailAddress IS NULL
Run Code Online (Sandbox Code Playgroud)
请不要使用它,因为它几乎肯定是不正确的(更不用说SELECT *),我忽略了contacts_ref_jobfunctions_3的逻辑来提供一个简单的例子.
有关连接的(非常)很好的解释,请尝试连接的这种可视化解释
| 归档时间: |
|
| 查看次数: |
252 次 |
| 最近记录: |