SQL多对多连接表的位置

时间:2016-09-05 16:18:13

标签: sql sql-server

我有以下(适度史诗般的查询),我一直在写

Select * 
from 
    (Select 
         Salutation, 
         FirstName, LastName, FullName, 
         PhotoUrl, CountryCode, Email,  Birthday, 
         Gender, HomePhone, M.MemberId, IDType, JoinDate, 
         HomeLocation, HomeLocationId, 
         Region.Name as RegionName, 
         M.MembershipId, 
         coalesce(case 
                     when Package.PackageIsReoccuring = 1 then 'Recurring' 
                     when Package.PackageIsSession = 1 then 'Paid In Full' 
                     when membership.TotalPrice = 0 then 'Free' 
                     when Package.PackagePayInFull = 1 then 'Paid In Full' 
                  end, 'N/A') as PackageTerm,
        coalesce(PackageType.Name, 'N/A') as PackageType,
        coalesce(membershipstate.name, 'N/A') as MembershipState,
        MembershipStartDate = 
           case 
              when membership.StartDate IS NULL 
                 then '' 
                 else CONVERT(varchar(50),membership.StartDate) 
           end,
       MembershipEndDate = 
           case 
              when membership.EndDate IS NULL 
                 then '' 
                 else CONVERT(varchar(50),membership.EndDate) 
           end,
       Region.Id as RegionId
   from  
       (select
            AspNetUsers.Salutation,
            AspNetUsers.FirstName, AspNetUsers.LastName,
            CONCAT (AspNetUsers.FirstName, ' ', AspNetUsers.LastName) as FullName,  
            AspNetUsers.PhotoUrl, AspNetUsers.CountryCode, AspNetUsers.Email,
            AspNetUsers.Birthday, AspNetUsers.Gender, 
            AspNetUsers.HomePhone as HomePhone,
            Member.Id as MemberId, Member.IDType, Member.JoinDate,
            HomeLocation.Name as HomeLocation,
            HomeLocation.Id as HomeLocationId,
            (case when (select top 1 id from membership where membership.memberid = Member.id and (membership.membershipstateid = 1 or membership.membershipstateid = 6)) IS NULL Then (select top 1 id from membership where membership.memberid = Member.id order by membership.enddate desc) ELSE (select top 1 id from membership where membership.memberid = Member.id and (membership.membershipstateid = 1 or membership.membershipstateid = 6)) END) as MembershipId
        from
            AspNetUsers
        join 
            Member on AspNetUsers.id = Member.aspnetuserid
        join 
            Location as HomeLocation on Member.HomeLocationId = HomeLocation.id) as M
   left join 
       Membership on M.MembershipId = Membership.Id
   left join 
       Package on Membership.packageid = Package.Id
   left join 
       PackageType on Package.packagetypeid = PackageType.Id
   left join 
       MembershipState on Membership.membershipstateid = MembershipState.Id
   left join 
       Region on Membership.RegionId = Region.Id) as Result
order by 
    Result.LastName desc

我有一个我想要使用的最终连接表,它是Region上的多对多关系。 Region有一个Join Table(RegionLocations),它是Region和Locations之间的连接。

通过下面的查询,我想获得HomeLocationId = 2的所有结果或者他有一个LocationId(来自RegionLocations),它也包含2. RegionId是一个可以为空的值,并且不会总是填充。

我怎么能得到这个?我是否需要将值返回CSV?这最后的障碍是一场战斗..

由于

1 个答案:

答案 0 :(得分:1)

你可以扩展这个:

left join 
    Region on Membership.RegionId = Region.Id) as Result

到此:

left join 
    Region on Membership.RegionId = Region.Id
where M.HomeLocationId = 2 
   or Region.Id in (select RegionId from RegionLocation where LocationId = 2)
) as Result

关于您的查询的其他一些评论:

字段MembershipStartDateMembershipEndDate可以更简洁地评估为:

COALESCE(CONVERT(varchar(50),membership.StartDate), '') as MembershipStartDate,
COALESCE(CONVERT(varchar(50),membership.EndDate), '') as MembershipEndDate,

内部字段MembershipIdcase when中定义了三个子查询,可以缩短为一个查询。它使用in而不是or条件,并以优先权的方式将其放在order by子句中:

        (select    top 1 id 
         from      membership 
         where     membership.memberid = Member.id 
         order by  case when membership.membershipstateid in (1,6) then 0 else 1 end,
                   membership.enddate desc
        ) as MembershipId

最后,如果您只有一个执行select * from (...) order by的外部查询,那么为什么不跳过该外部查询并直接在内部查询上执行order by