在 SQL 连接语句中选择一对多关系中最匹配的记录

Posted

技术标签:

【中文标题】在 SQL 连接语句中选择一对多关系中最匹配的记录【英文标题】:Selecting the top matching record of a one to many relationship on a SQL join statement 【发布时间】:2014-01-04 12:52:59 【问题描述】:

我有一个问题可能很简单,但无论如何我都不是 SQL 专家。 我有这个有 3 个连接的查询,第 3 个是一对多关系,我试图获得前 1 个。在这种情况下,这将是支持呼叫的最后一次编辑。

信息来自 4 个表,CASE 用于基本案例详细信息,CONTACT1 和 CONTACT2 用于联系人信息,NOTES 用于所述案例的注释,此 NOTES 表为在该案例中输入的每个注释创建 1 个条目。我想创建一个包含上次输入时间戳的仪表板。

我尝试在连接中添加一个 Select top (1),尝试了所有可能的连接选项,并将 Max (C3.MODIFIEDDATE) 与 Group By 一起使用,但我总是以每张票的 NOTES 中的所有记录结束。

这是我的查询:

SELECT c.NUMBER as [Case Number], c.OWNER as [Assigned To], case c.status when 0 then '<unknown>' when 1 then 'Assigned' when 2 then 'Reassigned' when 3 then 'Escalated' when 4 then 'Resolved' 
else cast(c.status as varchar(50)) end as [Case Status], c.SUBJECT as [Subject], c.OFFERING as [Next Step], DATEADD(day,DATEDIFF(day,0,c.CREATED_DATE),0) as [Created on], c1.CONTACT 
as [Primary Contact], c1.COMPANY as [Company], c3.MODIFIEDDATE as [Last Edit], c3.MODIFIEDBY as [Last Agent]

FROM CASES c left join(CONTACT1 c1 inner join CONTACT2 c2 on c1.ACCOUNTNO = c2.ACCOUNTNO ) on c1.ACCOUNTNO = c.ACCOUNTNO 
   left join NOTES as c3 on c3.LOPRECID =c.recid -- That's the one that has a 1 to many resolve


WHERE (  c.IS_TEMPLATE = 0  AND   c.STATUS IN ( 1,2,3 ) and c3.rectype='CS' )
ORDER BY [Company] asc, c3.modifieddate desc

任何建议都将不胜感激

【问题讨论】:

top 1 with a left join 的可能重复项 【参考方案1】:
LEFT JOIN 
(
   SELECT LOPRECID, MODIFIEDDATE, MODIFIEDBY, 
     rn = ROW_NUMBER() OVER (PARTITION BY LOPRECID ORDER BY MODIFIEDDATE DESC)
   FROM dbo.Notes
) AS C3
ON C3.LOPRECID = c.recid AND C3.rn = 1

【讨论】:

对不起,我没有早点回复你们,我期待收到一封电子邮件,让我知道人们已经回答了我的问题。那行得通,现在我只需要在应用程序本身中测试它。感谢您的帮助【参考方案2】:

一种方式(也有其他方式)替换

left join NOTES as c3 on c3.LOPRECID =c.recid

OUTER APPLY (SELECT TOP 1 MODIFIEDDATE, MODIFIEDBY 
             FROM NOTES AS N 
             WHERE N.LOPRECID = c.recid AND N.rectype='CS'
             ORDER BY MODIFIEDDATE DESC
) AS c3

并从 WHERE 子句中删除 c3.rectype='CS'

您需要确保在 NOTES 中没有满足 rectype='CS' 要求的行的情况下,这会产生所需的结果,因为这会为您的要求添加一点沙子。

【讨论】:

请求者想要最近的行,所以如果没有ORDER BY 子句,您的查询可能会返回不正确的结果。 @ErikE - 我在问题中错过了这一点。感谢您指出。我已经编辑了我的答案。

以上是关于在 SQL 连接语句中选择一对多关系中最匹配的记录的主要内容,如果未能解决你的问题,请参考以下文章

使用左连接选择一对多关系中的第一条记录

sql 一对多关系随机查一条

sql 一对多的查询

使用SQL Server创建一对多关系

Realm Swift 选择与一对多关系实体中的一个字段匹配的所有值

mysql 多对多映射关系的筛选SQL怎么写