T-SQL: одни и те же поля с использованием нескольких объединений - PullRequest
1 голос
/ 26 марта 2012

Я просмотрел похожие вопросы, но не смог найти ответ на свой конкретный вопрос. Я работаю с SQL Server 2008 (T-SQL в SQL Server Management Studio) (но гораздо чаще используется для Oracle и Crystal Reports).

Упрощенный сценарий:

Таблица Клиент

customerID (pk)...

Таблица Страховое покрытие

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

Таблица Страховая компания

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

Я чувствую себя очень глупо, не в состоянии понять это. Один клиент может иметь до трех страховок. Для этого было бы легко написать несколько запросов, но мне нужно настроить его так, чтобы он мог запускаться автоматически 1 раз в месяц. Я использовал одну и ту же таблицу несколько раз в одном и том же отчете, используя псевдонимы для объединений, но здесь это не сработает из-за критериев InsuranceCoverage.line, верно? Подзапрос в предложении from является ответом?

Ответы [ 3 ]

2 голосов
/ 27 марта 2012

Я настроил некоторые переменные таблицы, чтобы показать, что этот запрос работает.Вам нужно будет заменить их реальными именами таблиц и столбцов.Я считаю, что что-то вроде этого будет работать для вас:

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 голосов
/ 27 марта 2012

Как то так?

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
1 голос
/ 26 марта 2012

вы можете сделать объединение 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

что-то в этом роде

edit: о,верно, если у них нет страховки, тогда поменяйте ее на левое соединение, например ...

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

... или что-то в этом роде:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...