【问题标题】:T-SQL: Same fields using multiple joinsT-SQL:使用多个连接的相同字段
【发布时间】:2012-03-26 19:46:15
【问题描述】:

我查看了类似的问题,但找不到特定问题的答案。我正在使用 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. Insurance 1 - InsuranceCompany 和 InsurancePlan 表中 InsuranceCoverage.line = 1 的列
  3. Insurance 2 - InsuranceCompany 和 InsurancePlan 表中 InsuranceCoverage.line = 2 的列
  4. Insurance 3 - InsuranceCompany 和 InsurancePlan 表中 InsuranceCoverage.line = 3 的列

我觉得自己很愚蠢,无法弄清楚这一点。一位客户最多可能拥有三份保险。这很容易为其编写多个查询,但我必须对其进行设置,以便它可以每月自动运行 1 次。我之前通过在连接上使用别名在同一个报告中多次使用同一个表,但是由于 InsuranceCoverage.line 标准,这在这里不起作用,对吧? from 子句中的子查询是答案吗?

【问题讨论】:

    标签: sql-server tsql subquery


    【解决方案1】:

    这样的?

    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】:

    我设置了一些表变量以显示此查询有效。您需要将它们替换为真实的表名和列名。我相信这样的事情会为你工作:

    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
    

    【讨论】:

    • 如果客户只有一个ins覆盖怎么办?
    • @Chris Shain:啊,他说最多3个保险...,我会修改它。谢谢。
    【解决方案3】:

    您可以将 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
    

    ...或类似的东西:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-15
      • 2010-09-07
      • 2013-10-26
      • 1970-01-01
      • 2011-06-11
      • 2011-11-28
      相关资源
      最近更新 更多