2012-03-26 66 views
1

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

简化的场景:

客户

customerID (pk)... 

InsuranceCoverage

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

InsuranceCompany

insCompanyID 
insCompanyName 
insCompanyAddr 

InsurancePlan

insPlanID 
insPlanName 
insPlanClass 

我需要一份报告,基本上返回以下的一行:

  1. 数列从Customer
  2. 保险1 - 列从InsuranceCompany和InsurancePlan表,其中InsuranceCoverage.line = 1
  3. 组保险2 - 从InsuranceCompany和InsurancePlan表中的列,其中InsuranceCoverage.line = 2
  4. 保险3 - 从InsuranceCompany和InsurancePlan表中的列,其中InsuranceCoverage.line = 3

我觉得很愚蠢不能够想出解决出。一位顾客可能有多达三项保险。这将很容易编写多个查询,但我必须设置它,以便它可以自动运行1x /月。我在同一份报告中多次使用同一张表,在之前使用别名,但由于保险标准.line条件,这不适用于此,对吧? from子句中的子查询是否是答案?

回答

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 
+0

我认为这是最好的情况下,一些客户没有保险。 – zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz 2012-03-26 20:09:33

+0

非常感谢你们。你的回答不仅回答了这个问题,而且帮助我解决了另一个问题。这个网站真棒。 – 2012-03-27 00:04:10

1

你可以做2 4工会,3,作为派生表,并加入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 

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

2

I S等一些表变量来显示这个查询的工作原理。您需要用真实的表格和列名称替换它们。我相信像这样的东西会适合你:

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 
+2

如果客户只有一个插件,该怎么办? – 2012-03-26 20:03:42

+0

切换到左连接。:) – 2012-03-26 20:10:49

+0

@Chris Shain:啊,他说了多达3项保险......,我会修改它。谢谢。 – 2012-03-26 20:11:42