【问题标题】:SQL Where in for Many to Many Join Table多对多连接表的 SQL 位置
【发布时间】:2016-09-05 16:18:13
【问题描述】:

我一直在写以下(中等史诗查询)

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 有一个连接表 (RegionLocations),它是 Region 和 Locations 之间的连接。

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

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

谢谢

【问题讨论】:

  • 为什么不在那里也使用子查询?
  • 我不确定在哪里添加子查询...我基本上需要获取 homelocationid 为 2 或 regionlocation 也为 2 的所有成员

标签: sql sql-server


【解决方案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

【讨论】:

  • 如果 regionid 为空并且我的左连接与连接是否正确,这是否考虑在内?我永远不知道它是否正确......不过,感谢您迄今为止的帮助!
  • 如果Region.Idnull,那么where 子句中的第二个条件将为假,那么一切都取决于第一个条件:M.HomeLocationId = 2。如果失败了,那就是不匹配。
  • 您的连接似乎没问题。当然,我不知道你数据的所有来龙去脉,以及你对每种情况的期望(有很多情况)。
  • 好的,谢谢...我想我需要好好检查一下我的数据...我遇到了一些不一致的地方
猜你喜欢
  • 2017-08-02
  • 2016-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-18
  • 2023-03-04
相关资源
最近更新 更多