T-SQL:使用多个连接的相同字段

时间:2012-03-26 19:46:15

标签: sql-server tsql subquery

我回顾了类似的问题,但无法找到我特定问题的答案。我正在使用SQL Server 2008(SQL Server Management Studio中的T-SQL)(但更多地用于Oracle和Crystal Reports)。

简化方案:

客户

customerID (pk)...

InsuranceCoverage

customerID (composite pk)
line (composite pk)
insCompanyID (fk)
insPlanID (fk)

InsuranceCompany

insCompanyID
insCompanyName
insCompanyAddr

InsurancePlan

insPlanID
insPlanName
insPlanClass

我需要一个基本上在一行上返回以下内容的报告:

  1. Customer
  2. 的几列
  3. 保险1 - 来自InsuranceCompany和InsurancePlan表的栏目,其中InsuranceCoverage.line = 1
  4. 保险2 - 来自InsuranceCompany和InsurancePlan表的栏目,其中InsuranceCoverage.line = 2
  5. 保险3 - 来自InsuranceCompany和InsurancePlan表的栏目,其中InsuranceCoverage.line = 3
  6. 我觉得非常愚蠢无法解决这个问题。一个客户可能最多有三个保险。这可以很容易地编写多个查询,但我必须设置它,以便它可以1x /月自动运行。我之前在联接上使用别名,在同一个报表中多次使用同一个表,但由于InsuranceCoverage.line标准,这在此处不起作用,对吧? from子句中的子查询是答案吗?

3 个答案:

答案 0 :(得分:2)

我设置了一些表变量来表明此查询有效。您需要使用真实的表名和列名替换它们。我相信这样的事情对你有用:

DECLARE @Customer TABLE (CustomerId INT)

DECLARE @InsuranceCoverage TABLE
(
    CustomerId INT
    , Line INT
    , InsuranceCompanyId INT
    , InsurancePlanId INT
)

DECLARE @InsuranceCompany TABLE
(
    Id INT
    , Name VARCHAR(100)
    , Addr VARCHAR(100)
)

DECLARE @InsurancePlan TABLE
(
    Id INT
    , Name VARCHAR(100)
    , Class VARCHAR(100)
)

SELECT
    C.* -- Customer colums.
    -- Insurance1 columns.
    , ICmp1.*
    , IP1.*
    -- Insurance2 columns.
    , ICmp2.*
    , IP2.*
    -- Insurance3 columns.
    , ICmp3.*
    , IP3.*
    FROM
    @Customer C
    LEFT JOIN @InsuranceCoverage ICov1          
        INNER JOIN @InsuranceCompany ICmp1
            ON ICmp1.Id = ICov1.InsuranceCompanyId
        INNER JOIN @InsurancePlan IP1
            ON IP1.Id = ICov1.InsurancePlanId
        ON ICov1.CustomerId = C.CustomerId
        AND ICov1.Line = 1
    LEFT JOIN @InsuranceCoverage ICov2
        INNER JOIN @InsuranceCompany ICmp2
            ON ICmp2.Id = ICov2.InsuranceCompanyId
        INNER JOIN @InsurancePlan IP2
            ON IP2.Id = ICov2.InsurancePlanId
        ON ICov2.CustomerId = C.CustomerId
        AND ICov2.Line = 2
    LEFT JOIN @InsuranceCoverage ICov3
        INNER JOIN @InsuranceCompany ICmp3
            ON ICmp3.Id = ICov3.InsuranceCompanyId
        INNER JOIN @InsurancePlan IP3
            ON IP3.Id = ICov3.InsurancePlanId
        ON ICov3.CustomerId = C.CustomerId
        AND ICov3.Line = 3

答案 1 :(得分:2)

这样的东西?

SELECT
    c.CustomerID,
    cov1.*,
    cov2.*,
    cov3.*,
    insco1.insCompanyName as insCompanyName1,
    insco2.insCompanyName as insCompanyName2,
    insco3.insCompanyName as insCompanyName3,
    etc...
FROM
    Customer c
    LEFT OUTER JOIN InsuranceCoverage cov1 on cov1.CustomerID = c.CustomerID AND cov1.line = 1
    LEFT OUTER JOIN InsuranceCoverage cov2 on cov2.CustomerID = c.CustomerID AND cov2.line = 2
    LEFT OUTER JOIN InsuranceCoverage cov3 on cov3.CustomerID = c.CustomerID AND cov3.line = 3
    JOIN InsuranceCompany insco1 on insco1.insCompanyID = cov1.insCompanyID
    JOIN InsuranceCompany insco2 on insco2.insCompanyID = cov2.insCompanyID
    JOIN InsuranceCompany insco3 on insco3.insCompanyID = cov3.insCompanyID
    JOIN InsurancePlan inspl1 on inspl1.insPlanID = cov1.insPlanID
    JOIN InsurancePlan inspl2 on inspl2.insPlanID = cov2.insPlanID
    JOIN InsurancePlan inspl3 on inspl3.insPlanID = cov3.insPlanID

答案 2 :(得分:1)

你可以做一个2,3,4的联合作为派生表并加入1,就像......

select t1.a,t1.b,t1.c, t2.d, t2.e, t2.f from customer t1, 
(select fk, d as d, 0 as e, 0 as f from ic where line=1
  union select fk, 0, e, 0 from ic where line=2
  union select fk, 0, 0, f from ic where line=3) as t2
where t1.pk = t2. fk

类似的东西

编辑:哦,对,如果他们没有保险,那么将其更改为左边的连接,如...

select t1.a,t1.b,t1.c, t2.d, t2.e, t2.f from customer t1 left join  
(select fk, d as d, 0 as e, 0 as f from ic where line=1
  union select fk, 0, e, 0 from ic where line=2
  union select fk, 0, 0, f from ic where line=3) as t2
 on t1.pk = t2.fk

......或类似的东西:)