简体   繁体   English

在多个连接中使用 TOP 1(或 CROSS APPLY)

[英]Using TOP 1 (or CROSS APPLY) within multiple joins

I've reviewed multiple Q&A involving TOP 1 and CROSS APPLY (including the very informative 2043259 ), but I still can't figure out how to solve my issue.我已经查看了多个涉及 TOP 1 和 CROSS APPLY 的问答(包括内容非常丰富的2043259 ),但我仍然不知道如何解决我的问题。 If I had a single join I'd be fine, but fitting TOP 1 into the middle of a chain of joins has stumped me.如果我有一个单一的连接,我会很好,但是将 TOP 1 放入连接链的中间让我很难过。

I have four tables and one of the tables contains multiple matches when joining due to a previous bug (since fixed) that created new records in the table instead of updating existing records.我有四个表,其中一个表在加入时包含多个匹配项,因为之前的错误(自已修复)在表中创建了新记录而不是更新现有记录。 In all cases, where there are multiple records, it is the top-most record that I want to use in one of my joins.在所有情况下,如果有多个记录,它是我想在我的一个联接中使用的最顶层的记录。 I don't have access to the table to clean up the extraneous data, so I just have to deal with it.我无权访问表来清理无关数据,所以我只需要处理它。

The purpose of my query is to return a list of all "Buildings" managed by a particular person (user choses a person's name and they get back a list of all buildings managed by that person).我查询的目的是返回由特定人员管理的所有“建筑物”的列表(用户选择一个人的姓名,他们会返回该人管理的所有建筑物的列表)。 My tables are:我的桌子是:

Building (a list of all buildings):建筑物(所有建筑物的列表):

BuildingId  BuildingName
1           Oak Tree Lane
2           Lighthoue Court
3           Fairview Lane
4           Starview Heights

WebBuildingMapping (mapping of BuidingId from Building table, that is part of an old system, and corresponding WebBuildingId in another piece of software): WebBuildingMapping(BuidingId 来自 Building 表的映射,它是旧系统的一部分,以及另一个软件中对应的 WebBuildingId):

BuildingId  WebBuildingId
1           201
2           202
3           203
4           204

WebBuildingContacts (list of ContactID for the building manager of each building). WebBuildingContacts(每个建筑物的建筑物经理的 ContactID 列表)。 This is the table with duplicate values - where I want to choose the TOP 1. In sample data below, there are two references to WebBuidingId = 203 (row 3 & row 5) - I only want to use row 3 data in my join.这是具有重复值的表 - 我想在其中选择 TOP 1。在下面的示例数据中,有两个对 WebBuidingId = 203(第 3 行和第 5 行)的引用 - 我只想在我的联接中使用第 3 行数据。

Id  WebBuildingId   ContactId
1   201             1301
2   202             1301
3   203             1303
4   204             1302
5   203             1302

Contacts (list of ContactIds and corresponding property manager Names)联系人(ContactIds 列表和相应的物业经理姓名)

ContactId   FullName
1301        John
1302        Mike
1303        Judy

As noted, in the example above, the table WebBuildingContact has two entries for the building with a WebBuidingId = 203 (row 3 and row 5).如前所述,在上面的示例中,表 WebBuildingContact 有两个用于建筑物的条目,WebBuidingId = 203(第 3 行和第 5 行)。 In my query, I want to select the top one (row 3).在我的查询中,我想 select 排在第一位(第 3 行)。

My original query for a list of buildings managed by 'Mike' is:我对“迈克”管理的建筑物列表的原始查询是:

SELECT BuildingName
FROM Building bu 
JOIN WebBuildingMapping wbm ON wbm.BuildingId = bu.BuildingId
JOIN WebBuildingContact wbc ON wbc.WebBuildingId = wbm.WebBuildingId
JOIN Contacts co ON co.ContactId = wbc.ContactId
WHERE co.FullName = 'Mike'

This returns 'Fairview Lane' and 'Starview Heights';这将返回“Fairview Lane”和“Starview Heights”; however, Judy manages 'Fairview Lane' (she's the top entry in the WebBuildingContacts table).但是,Judy 管理“Fairview Lane”(她是 WebBuildingContacts 表中的顶部条目)。 To modify the query and eliminate row 5 in WebBuildingContacts from the join, I did the following:要修改查询并从联接中删除 WebBuildingContacts 中的第 5 行,我执行了以下操作:

SELECT BuildingName
FROM Building bu 
JOIN WebBuildingMapping wbm ON wbm.BuildingId = bu.BuildingId
JOIN WebBuildingContact wbc ON wbc.WebBuildingId = 
    (
    SELECT TOP 1 WebBuildingId
    FROM WebBuildingContact
    WHERE WebBuildingContact.WebBuildingId = wbm.WebBuildingId
    )
JOIN Contacts co ON co.ContactId = wbc.ContactId
WHERE co.FullName = 'Mike'

When I try this;当我尝试这个时; however, I get the same result set (ie it returns 'Mike' as manager for 2 buildings).但是,我得到了相同的结果集(即它返回 'Mike' 作为 2 个建筑物的经理)。 I've also made various attempts to use CROSS APPLY but I just end up with 'The multi-part identifier could not be bound', which is a whole other rabbit hole to go down.我也进行了各种尝试使用 CROSS APPLY 但我最终得到了“无法绑定多部分标识符”,这是 go 的另一个兔子洞。

Thanks for taking the time to read this.感谢您抽时间阅读。 I am new this so I hope it's clear and not too similar to other questions already asked on this topic.我是新来的,所以我希望它很清楚,并且与已经就该主题提出的其他问题不太相似。

You could try this:你可以试试这个:

SELECT bu2.BuildingName
FROM building bu2
WHERE bu2.BuildingId IN 
    (SELECT MAX(bu.BuildingId)
    FROM Building bu 
    JOIN WebBuildingMapping wbm ON wbm.BuildingId = bu.BuildingId
    JOIN WebBuildingContact wbc ON wbc.WebBuildingId = wbm.WebBuildingId
    JOIN Contacts co ON co.ContactId = wbc.ContactId
    WHERE co.FullName = 'Mike'
    );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM