数据集市 - 如何处理一对多关系?

时间:2014-08-13 11:42:17

标签: sql join ssis duplicates data-warehouse

我有以下情况,我不知道如何处理: 有一个表Inovice_Item,Service和ServiceLang。 Invoice_item表具有FK_Service密钥(一对一)。服务表有FK_Service_Lang键。 ServiceLang表具有FK_Service键,因此它可以实现多对多的关系。

换句话说,Invoice_Item可以有多个ServiceLang记录,这意味着当我进行连接查询时,invoice_item记录会重复。处理这种情况有哪些选择?

我想在多维数据集中拥有ServiceLang维度,但我不知道如何处理由join引起的重复。

修改

我做了一个例子:

Schema

enter image description here

查询如下:

-- One lang for service A, two langs for service B
select * from ServiceLang

-- Two records: A and B
select * from Service

-- Total amount is 20
select * from InvoiceItem

-- Query to populate Fact table
-- Total amount is 30
select * 
from InvoiceItem II
inner join Service S on II.FK_Service = S.PK_Service
inner join ServiceLang SL on S.PK_Service = SL.FK_Service

因此,如果有两个Service_Lang记录与一个服务相关,那么重复行意味着总服务量将是30但应该是20.所以,我的问题是如何处理这些情况?

1 个答案:

答案 0 :(得分:0)

从描述中你错了。每个Invoice_Item只有一个Service,每个Service只有一个Service_Lang。但是,每个Service_Lang都有许多服务记录,每个服务都有许多Invoice_Item记录

关系是

    Invoice (n) <- (1) Service (n) <- (1) Service_Item

因此JOIN将是

    Select Invoice_Item.*, Service_Lang.WhateverColumnYouWant
      From Invoice_Item
           Inner Join Service On Service.Key = Invoice_Item.FK_Service_Key
           Inner Join Service_Lang On Service_Lang.Key = Service.FK_Service_Lang_Key

编辑:因此服务表上有一个FK_Service_Lang键,在这种情况下,您只能为与该服务关联的语言选择一个可能的值。您可以根据您的首选语言选择Min,Max或某些推导,例如......

Select InvoiceItem.*,
       Case When Exists (Select 1 From ServiceLang
                          Where ServiceLang.FK_Service = InvoiceItem.FK_Service
                            And ServiceLang.Name = 'English')
            Then 'English'
            Else (Select Max(Name) From ServiceLang
                   Where ServiceLang.FK_Service = InvoiceItem.FK_Service)
            End As ServiceLanguage,
       (Select Max(Name) From ServiceLang
         Where ServiceLang.FK_Service = InvoiceItem.FK_Service) As MaxLanguage,
       (Select Min(Name) From ServiceLang
         Where ServiceLang.FK_Service = InvoiceItem.FK_Service) As MinLanguage
  From InvoiceItem

我不知道你的ServiceLang表有多大,但是好的做法是确保FK_Service列上有一个键