【问题标题】:SQL Server join across multiple tablesSQL Server 跨多个表连接
【发布时间】:2014-12-29 16:32:00
【问题描述】:

希望是一个简单的 MS SQL 问题!我有四张桌子:

Portfolio:
int portfolioId, string portfolioName
1,'PortFolio 1'

Trip:
int tripId, int portfolioId, int tripType, int maxPeople, string tripName
1, 1, 1, 20, 'Trip A'
2, 1, 1, 21, ’Trip B'
3, 1, 2, 22, ’Trip C'

Person:
int personId, int personStatus, string personName
1, 14, ‘Person 1'
2, 15, ‘Person 2'
3, 16, ‘Person 3'

TripPerson:
int personId, int tripId
1, 1
1, 3
2, 1
2, 2

对于给定的投资组合 ID,我正在尝试编写一个干净的查询,该查询将为我提供以下列:

tripId, countA, countB, tripType, tripName

在哪里: CountA:是行程中的总人数。 CountB:是参加该旅行且至少参加过另一次类型为“2”的旅行的总人数。 返回的行数必须与与portfolioId = 1 的投资组合相关的旅行次数相匹配,按tripName 排序。

想法?我正在使用 MS SQL,对 SQL 有基本的了解,这让我很着急。

【问题讨论】:

    标签: sql sql-server sql-server-2012


    【解决方案1】:

    您可以将查询编写为:

    With CTE1 as
    (
    -- Total number of persons on a trip:
    select count(T.personId) as CountA , tripId
    from TripPerson T
    group by T.tripId
    ),
    CTE2 as 
    (
        -- Total number of people who are on a trip that have also been on 
        -- at least one other trip with type of '2'.
        select Count (T2.personId)as CountB , CTE1.tripId ,CTE1.CountA
        from TripPerson T2
        inner join  TripPerson T3 on T2.personId = T3.personId and T3.tripId =2
        right join CTE1 on CTE1.tripId = T2.tripId
        group by CTE1.tripId,CTE1.CountA
    ) 
    select CTE2.tripId, CTE2.CountA, CTE2.CountB, Trip.tripType, Trip.tripName
    from CTE2
    inner join Trip on Trip.tripId = CTE2.tripId
    inner join Portfolio P on P.portfolioId = Trip.portfolioId
    

    DEMO

    【讨论】:

    • 我最终使用了 CTE——它们永远地改变了我的 mssql 生活。
    【解决方案2】:

    一个选项是您可以使用子查询来获取 countA 和 countB,因此查询如下所示:

    select trip.tripId, trip.tripType, trip.tripName, 
    (select count(personId) from TripPerson where tripId = trip.tripId) as countA, 
    (select count(personId) from TripPerson where tripId IN (trip.tripId, 2)) as countB 
    from Trip trip 
    where portfolioId = 1 order by trip.tripName
    

    【讨论】:

      【解决方案3】:

      这将通过加入tripperson 来查找计数并再次使用left join to person 来查找多次旅行的同一个人来获得结果。

      SELECT t.tripId, count(p.personid) countA, count(p2.personid) countB, 
             t.tripType, t.tripName, t.portfolioid
      FROM TRIP t
      JOIN TripPerson p ON p.tripid = t.tripid
      LEFT JOIN (select tp.personid, count(*) cnt FROM TripPerson tp group by tp.personid) p2 
           ON p2.personid = p.personid and p2.cnt > 1
      group by t.tripId, t.tripType, t.tripName, t.portfolioid
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-22
        • 1970-01-01
        相关资源
        最近更新 更多