Sql 多次加入表

Sql 多次加入表,sql,sql-server-2008,tsql,join,Sql,Sql Server 2008,Tsql,Join,我有三个表:Account、Management和ManagementAccountLookup Account表包含位置。管理表包含业务层次结构中每个级别的记录。管理表还包含一个值(LevelID),该值指示记录属于层次结构中的哪个级别。ManagementAccountLookup表是连接它们的查找表 我在编写查询以获取所有帐户及其两个关联管理记录时遇到问题 例如:一个帐户可能有5个或更多与之关联的管理记录,但我只关心两个具有品牌或地区级别ID的特定管理层。另外,我只希望一个帐户在结果网格中

我有三个表:
Account
Management
ManagementAccountLookup

Account表包含位置。管理表包含业务层次结构中每个级别的记录。管理表还包含一个值(LevelID),该值指示记录属于层次结构中的哪个级别。ManagementAccountLookup表是连接它们的查找表

我在编写查询以获取所有帐户及其两个关联管理记录时遇到问题

例如:一个帐户可能有5个或更多与之关联的管理记录,但我只关心两个具有品牌或地区级别ID的特定管理层。另外,我只希望一个帐户在结果网格中显示一次

结果集应如下所示:

AccountID   Brand      Region
---------   --------   ------
account1    Wendys     East US
account2    McDonalds  West US
这似乎是一个简单的问题,但我还没有弄清楚如何得到这个结果。我尝试过自联接、子查询以及我能想到的所有其他方法,但我似乎无法将结果放在一行中

任何帮助都将不胜感激

*编辑: ManagementAccountLookup有两个字段(AccountID、ManagementID)。这是另外两张表的PK。
管理层有一个列级别ID,您可以通过该ID判断记录是否为品牌、地区、地区等


品牌和地区将在管理表中分为两行。我需要结果网格将它们放在同一行。

您需要添加两次ManagementAccountLookup/Management组合才能在一行中获取信息。我将
LevelID
标准直接放在join中,以便在需要时简化到左连接的可能转换

select Account.AccountID,
       m_brand.Name Brand,
       m_region.Name Region
  from Account
 inner join ManagementAccountLookup mal_brand
    on Account.AccountID = mal_brand.AccountID
 inner join Management m_brand
    on mal_brand.ManagementID = m_brand.ManagementID
   and m_brand.LevelID = @Insert_Management_Brand_Level_Here
 inner join ManagementAccountLookup mal_region
    on Account.AccountID = mal_region.AccountID
 inner join Management m_region
    on mal_region.ManagementID = m_region.ManagementID
   and m_region.LevelID = @Insert_Management_Region_Level_Here
编辑:如果需要显示所有帐户,可以使用括号中的左/内联接组合:

select Account.AccountID,
       m_brand.Name Brand,
       m_region.Name Region
  from Account
  left join 
  (
       ManagementAccountLookup mal_brand
       inner join Management m_brand
         on mal_brand.ManagementID = m_brand.ManagementID
        and m_brand.LevelID = @Insert_Management_Brand_Level_Here
 )
   on Account.AccountID = mal_brand.AccountID
 left join 
 (
       ManagementAccountLookup mal_region
       inner join Management m_region
          on mal_region.ManagementID = m_region.ManagementID
         and m_region.LevelID = @Insert_Management_Region_Level_Here
 )
    on Account.AccountID = mal_region.AccountID
为了使其更具可读性,您可以使用CTE:

; with mal_level as (
  select AccountID,
         m.LevelID,
         m.Name
    from ManagementAccountLookup mal
   inner join Management m
      on mal.ManagementID = m.ManagementID
)
select Account.AccountID,
       m_brand.Name Brand,
       m_region.Name Region
  from Account
  left join mal_level m_brand
    on Account.AccountID = m_brand.AccountID
   and m_brand.LevelID = @Insert_Management_Brand_Level_Here
  left join mal_level m_region
    on Account.AccountID = m_region.AccountID
   and m_region.LevelID = @Insert_Management_Region_Level_Here
或:


也许你可以给我们看看这个表的模式。我们想帮助您,但我们不知道要加入哪些字段抱歉,我应该这么做,我只是不想添加一堆不必要的数据,让我的问题变得更加混乱。我做了一个编辑,使它更容易理解表的结构。谢谢你的意见,以后的问题我会记住的。太棒了!这看起来很有效。明天我会做更多的测试来确定,但我想这就是我需要的。另外,感谢您猜测表结构,为我提供了大量的复制和粘贴代码供我测试。我尝试过类似的方法,但我加入了ManagementAccountLookup表一次,然后加入了管理表两次。这就是我被挂断电话的地方。我对这句话还有一个问题。如果我需要允许客户在网格中显示,即使他们没有关联的区域或品牌,我将如何进行?我不能只是将连接更改为左连接,因为这样会产生大量重复。我想出的唯一方法(这不太好)是将结果合并到另一个查询中,对所有没有管理的帐户进行查询。有什么建议吗?@Justin很抱歉耽搁了,我昨天休假了。请检查我更新的答案。非常感谢!我责备自己没有发现第一个查询中缺少的只是括号。我昨天创建了一个视图,它的基本功能与CTE相同。我以前从未见过这样做,但我更喜欢它,而不是我创建的视图。我以前也从未见过外部应用方法。非常感谢你的帮助,我从中学到了很多。(另外,我对你的答案做了一点修改,因为如果不在括号后加上“as something”,申请就不起作用了。显然,我的修改在他们发布之前必须经过审核)。
select Account.AccountID,
       b.Brand,
       r.Region
  from Account
 outer apply
 (
       select m_brand.Name Brand
         from ManagementAccountLookup mal_brand
        inner join Management m_brand
           on mal_brand.ManagementID = m_brand.ManagementID
          and m_brand.LevelID = @Insert_Management_Brand_Level_Here
        where mal_brand.AccountID = Account.AccountID
 ) b
 outer apply
 (
       select m_region.Name Region
         from ManagementAccountLookup mal_region
        inner join Management m_region
           on mal_region.ManagementID = m_region.ManagementID
          and m_region.LevelID = @Insert_Management_Region_Level_Here
        where mal_region.AccountID = Account.AccountID
 ) r