2013-05-27 3 views
1

이보기는 정상적으로 작동합니다. 그 2008 R2UNION 회수 복제를 사용하여 선택

CREATE view vwQry_LicencePayments 
as 

select 
P.*, 
LT.LicenceTypeDesc, FT.FeeTypeDesc, FT.ThroughputText, FT.Prorata as IsProrata, PT.PaymentStatusDesc, PT.IsPaid, 
E.EntityType as HolderEntityType, E.EntityTypeDesc as HolderEntityTypeDesc, E.PersonTitle, E.PersonFirstname, E.PersonSurname, 
E.OrganisationName, E.FullName as HolderFullName, 
E.MailAddress as HolderMailAddress, E.Suburb as HolderSuburb, E.State as HolderState, E.Postcode as HolderPostcode, 
E.Mobile as HolderMobile, E.Email, E.PFN as HolderPFN 
from 
rptPayment P 
inner join vwQry_xhsEntity_Base E on P.HolderHistoryID = E.HistoryID 
inner join LicenceType LT on P.LicenceTypeID=LT.LicenceTypeID 
inner join LicenceFeeType FT on P.FeeTypeID=FT.FeeTypeID 
inner join PaymentStatusType PT on P.PaymentStatusID = PT.PaymentStatusID 

union ALL 

select 
P.*, 
LT.LicenceTypeDesc, FT.FeeTypeDesc, FT.ThroughputText, FT.Prorata as IsProrata, PT.PaymentStatusDesc, PT.IsPaid, 
E.EntityType as HolderEntityType, E.EntityTypeDesc as HolderEntityTypeDesc, E.PersonTitle, E.PersonFirstname, E.PersonSurname, 
E.OrganisationName, E.FullName as HolderFullName, 
E.MailAddress as HolderMailAddress, E.Suburb as HolderSuburb, E.State as HolderState, E.Postcode as HolderPostcode, 
E.Mobile as HolderMobile, E.Email, E.PFN as HolderPFN 
from 
(select * from rptPayment where HolderHistoryID is null) P 
inner join vwQry_Entity E on P.HolderID = E.EntityID 
inner join LicenceType LT on P.LicenceTypeID=LT.LicenceTypeID 
inner join LicenceFeeType FT on P.FeeTypeID=FT.FeeTypeID 
inner join PaymentStatusType PT on P.PaymentStatusID = PT.PaymentStatusID 

요구 사항은 지불 날짜 (LP.dateTimeStamp)를 포함하는 SQLServer에 얘기 보고서 건물 마법사에서 사용 내놓았다. 따라서 추가 필드 (LP.dateTimeStamp)와 두 개의 조인 (licenceFeePaymenttble 및 licencePaymenttble)을 추가하면 필연적으로 결과 집합에 중복이 발생합니다. 예를 들어 면허가 세 번의 별도 지불로 지불 되었다면 licencefeePayment 테이블에 세 개의 레코드가있을 것이라고 가정합니다. 그들은 내가 만든 변경 :

CREATE view vwQry_LicencePayments 
as 

select 
P.*, 
LT.LicenceTypeDesc, FT.FeeTypeDesc, FT.ThroughputText, FT.Prorata as IsProrata, PT.PaymentStatusDesc, PT.IsPaid, 
E.EntityType as HolderEntityType, E.EntityTypeDesc as HolderEntityTypeDesc, E.PersonTitle, E.PersonFirstname, E.PersonSurname, 
E.OrganisationName, E.FullName as HolderFullName, 
E.MailAddress as HolderMailAddress, E.Suburb as HolderSuburb, E.State as HolderState, E.Postcode as HolderPostcode, 
E.Mobile as HolderMobile, E.Email, E.PFN as HolderPFN, LP.DatetimeStamp AS DatetimeStamp 
from 
rptPayment P 
inner join vwQry_xhsEntity_Base E on P.HolderHistoryID = E.HistoryID 
inner join LicenceType LT on P.LicenceTypeID=LT.LicenceTypeID 
inner join LicenceFeeType FT on P.FeeTypeID=FT.FeeTypeID 
inner join PaymentStatusType PT on P.PaymentStatusID = PT.PaymentStatusID 
     inner join licenceFeePayment LFP on P.licenceID = LFP.licenceID 
     inner join licencePayment LP on LFP.paymentID = LP.paymentID 

union ALL 

select 
P.*, 
LT.LicenceTypeDesc, FT.FeeTypeDesc, FT.ThroughputText, FT.Prorata as IsProrata, PT.PaymentStatusDesc, PT.IsPaid, 
E.EntityType as HolderEntityType, E.EntityTypeDesc as HolderEntityTypeDesc, E.PersonTitle, E.PersonFirstname, E.PersonSurname, 
E.OrganisationName, E.FullName as HolderFullName, 
E.MailAddress as HolderMailAddress, E.Suburb as HolderSuburb, E.State as HolderState, E.Postcode as HolderPostcode, 
E.Mobile as HolderMobile, E.Email, E.PFN as HolderPFN, LP.DatetimeStamp AS DatetimeStamp 
from 
(select * from rptPayment where HolderHistoryID is null) P 
inner join vwQry_Entity E on P.HolderID = E.EntityID 
inner join LicenceType LT on P.LicenceTypeID=LT.LicenceTypeID 
inner join LicenceFeeType FT on P.FeeTypeID=FT.FeeTypeID 
inner join PaymentStatusType PT on P.PaymentStatusID = PT.PaymentStatusID 
     inner join licenceFeePayment LFP on P.licenceID = LFP.licenceID 
     inner join licencePayment LP on LFP.paymentID = LP.paymentID 

도움을 주시면 감사하겠습니다. 어떻게이 두 테이블을 결합하고 중복을 피할 수 있습니까?

@ 등록 사용자는 내가 그렇게 했음에도 불구하고 내 UNION에서 ALL을 모두 제거하는 것만 큼 간단하지 않다고 지적했습니다.

@ 등록 사용자는 유용한 답장을 보내 주셔서 감사합니다. 귀하의 도움을 바탕으로 내 쿼리를 변경했습니다. 이제 또 다른 작은 문제가 있습니다. 'paymentType'테이블의 'PaymentTypeDesc'라는 필드를 추가했습니다. 이 테이블이 'LicencePayment'를 통해 조인 할 때 하위 쿼리에 배치해야했습니다. 나는 지금도 믿을 수 있기 때문에 여전히 복제본을 얻고 있습니다. 복수 지불이 면허증에 들어올 수있을뿐만 아니라 여러 다른 출처의 EF EFTPOS, 현금 등에서 올 수 있습니다 ....

지불 거래뿐만 아니라 여러 지불 유형? 여기 내 변경된 작업 쿼리는 당신의 도움을 사용하여 이후 : 켄이 지적 하듯이

CREATE view vwQry_LicencePaymentsNew 
as 

select 
P.*, 
LT.LicenceTypeDesc, FT.FeeTypeDesc, FT.ThroughputText, FT.Prorata as IsProrata, PT.PaymentStatusDesc, PT.IsPaid, 
E.EntityType as HolderEntityType, E.EntityTypeDesc as HolderEntityTypeDesc, E.PersonTitle, E.PersonFirstname, E.PersonSurname, 
E.OrganisationName, E.FullName as HolderFullName, 
E.MailAddress as HolderMailAddress, E.Suburb as HolderSuburb, E.State as HolderState, E.Postcode as HolderPostcode, 
E.Mobile as HolderMobile, E.Email, E.PFN as HolderPFN 
    , lic.VehicleRegNo as VehicleRegNo 
    , payment.PaymentTypeDesc as PaymentTypeDesc 
    , S.StatusTypeDesc as StatusTypeDesc 
    , Payment.LastPaymentDate as DatetimeStamp 
    -- , Payment.FirstPaymentDate 
from 
rptPayment P 
inner join vwQry_xhsEntity_Base E on P.HolderHistoryID = E.HistoryID 
inner join LicenceType LT on P.LicenceTypeID=LT.LicenceTypeID 
inner join LicenceFeeType FT on P.FeeTypeID=FT.FeeTypeID 
inner join PaymentStatusType PT on P.PaymentStatusID = PT.PaymentStatusID 
inner join licence Lic on P.licenceID = lic.licenceID 
inner join vwLicCurrentStatus S on P.LicenceID=S.LicenceID 
inner join 
    (SELECT LFP.licenceID 
     , FirstPaymentDate = MIN(LP.DatetimeStamp) 
     , LastPaymentDate = MAX(LP.DatetimeStamp) 
     , PType.PaymentTypeDesc 
    FROM licenceFeePayment LFP 
    INNER JOIN licencePayment LP 
     on LFP.paymentID = LP.paymentID 
    INNER JOIN paymentType PType 
     on LP.paymentTypeID = PType.paymentTypeID 
    GROUP BY lfp.licenceID, PType.PaymentTypeDesc) Payment 
    ON P.licenceID = Payment.licenceID 

union 

select 
P.*, 
LT.LicenceTypeDesc, FT.FeeTypeDesc, FT.ThroughputText, FT.Prorata as IsProrata, PT.PaymentStatusDesc, PT.IsPaid, 
E.EntityType as HolderEntityType, E.EntityTypeDesc as HolderEntityTypeDesc, E.PersonTitle, E.PersonFirstname, E.PersonSurname, 
E.OrganisationName, E.FullName as HolderFullName, 
E.MailAddress as HolderMailAddress, E.Suburb as HolderSuburb, E.State as HolderState, E.Postcode as HolderPostcode, 
E.Mobile as HolderMobile, E.Email, E.PFN as HolderPFN 
    , lic.VehicleRegNo as VehicleRegNo 
    , payment.PaymentTypeDesc as PaymentTypeDesc 
    , S.StatusTypeDesc as StatusTypeDesc 
    , Payment.LastPaymentDate as DatetimeStamp 
    -- , Payment.FirstPaymentDate 

from rptPayment P 
inner join vwQry_xhsEntity_Base E on P.HolderHistoryID = E.HistoryID 
inner join LicenceType LT on P.LicenceTypeID=LT.LicenceTypeID 
inner join LicenceFeeType FT on P.FeeTypeID=FT.FeeTypeID 
inner join PaymentStatusType PT on P.PaymentStatusID = PT.PaymentStatusID 
inner join licence Lic on P.licenceID = lic.licenceID 
inner join vwLicCurrentStatus S on P.LicenceID=S.LicenceID 
inner join 
    (SELECT LFP.licenceID 
     , FirstPaymentDate = MIN(LP.DatetimeStamp) 
     , LastPaymentDate = MAX(LP.DatetimeStamp) 
     , PType.PaymentTypeDesc 
    FROM licenceFeePayment LFP 
    INNER JOIN licencePayment LP 
     on LFP.paymentID = LP.paymentID 
    INNER JOIN paymentType PType 
     on LP.paymentTypeID = PType.paymentTypeID 

    GROUP BY lfp.licenceID, PType.PaymentTypeDesc) Payment 
    ON P.licenceID = Payment.licenceID 
+0

'UNION' 문에서'ALL '을 제거하십시오. –

+0

@Ken 시간 내 주셔서 감사합니다. 나는 아직도 도움이 될 문제가있는 게시물을 추가했다. 등록 된 사용자가 ALL을 제거하는 것만 큼 간단하지 않다고 지적한만큼 – Mat41

+0

자세한 정보를 제공해야합니다 (일부 샘플 데이터와 해당 데이터에서 원하는 출력과 같음). 그것 없이는, 우리는 단지 문제가 무엇인지 추측 할 수 있으며, 그것은 StackOverflow가 작동하는 방식이 아닙니다. –

답변

1

참조하십시오. LastPaymentDate의 경우 기본적으로 마지막 DatetimeStamp가 승리 기록임을 결정했습니다. 이 레코드는 가장 간단한 방법 인 하위 쿼리의 열 최대 값을 사용하여 선택되었습니다. 지불 유형 설명, 지불 방법 또는 기타 지불 방법 속성이 여러 개인 경우 하나의 수상자를 선택하거나 함께 값을 집계해야합니다. 이것은 여러 가지 옵션을 잎 :

  1. 당신이 마지막 지불의 특성을 원한다면, 당신은 당신이 마지막 행에 데이터에 가입 제한 다음 ROW_NUMBER() 집계 윈도우 기능을 사용할 수 있습니다. 이는 대용량 데이터 세트의 경우 비용이 많이 들지만, 트랜잭션 시스템 자체 또는 일반 ETL 프로세스의 부분 데이터 세트에 값을 할당 할 수 있습니다. 데이터 세트가 상대적으로 작 으면 비용은 사소할 수 있습니다.

  2. 신뢰할 수있는 마지막 수정 날짜가 각 테이블에있는 경우 마지막으로 수정 한 날짜와 필터를 반환하여이 조건에 맞는 행으로 하위 쿼리를 실행할 수 있습니다. 이 방법은 성능이 좋지 않을 수도 있으며 여러 행의 수정 날짜가 동일하면 여러 행을 반환 할 수 있습니다.

  3. 선택한 결제 수단, 소스 또는 기타 속성을 모두 하나의 필드로 연결할 수 있습니다. 이것은 일반적으로 사용자가 값을 분리해야 할 수도 있기 때문에 좋지 않은 해결책이지만, 어떤 경우에는 이것이 정확한 해결책입니다. 이것이 올바른 해결책인지 여부를 결정하기 위해 사업주를해야합니다.

  4. 이 데이터를 요청한 업체 대표에게 이야기하고 데이터가 어떻게 작동하는지 그리고 어떻게 데이터를 제공 할 수 있는지에 대해 설명 할 수 있습니다. 일부 사용자는 마지막 결제 속성을 원할 수 있으며, 일부는 연결된 데이터를 원할 수도 있고, 일부 사용자는 전체 기록을 원할 수도 있습니다. 이는 별도의 집계되지 않은 결제 세부 정보 보고서를 제공해야 할 수도 있음을 의미합니다. 전제 조건을 세우고 솔루션을 코딩하기 전에 이해 관계자와 함께 검토하고 비즈니스의 요구를 충족시키지 못하기 때문에 전체 솔루션을 다시 코딩해야한다는 사실을 확인하는 것이 좋습니다. 아래

ORIGINAL RESPONSE LicensePayment 테이블은 다음에 충분하지 않을 UNION ALL로 변경 UNION 여러 고유 값을 포함하는 경우. 이 테이블이 첫 번째 지불 날짜, 마지막 지불 날짜 또는 둘 모두를 별도의 필드에 가져와야하는지 여부를 결정해야합니다. 이 작업은 (1) LicensePayment 테이블에 대한 조인을 하위 쿼리로 변환하거나, (2) LicensePayment 데이터를 별도로 집계하고 집계 된 테이블에 가입하는 방법으로 수행 할 수 있습니다. 다음은 첫 번째 방법론을 사용하는 샘플 쿼리입니다.

CREATE view vwQry_LicencePayments 
as 

select 
P.*, 
LT.LicenceTypeDesc, FT.FeeTypeDesc, FT.ThroughputText, FT.Prorata as IsProrata, PT.PaymentStatusDesc, PT.IsPaid, 
E.EntityType as HolderEntityType, E.EntityTypeDesc as HolderEntityTypeDesc, E.PersonTitle, E.PersonFirstname, E.PersonSurname, 
E.OrganisationName, E.FullName as HolderFullName, 
E.MailAddress as HolderMailAddress, E.Suburb as HolderSuburb, E.State as HolderState, E.Postcode as HolderPostcode, 
E.Mobile as HolderMobile, E.Email, E.PFN as HolderPFN 
    , Payment.FirstPaymentDate 
    , Payment.LastPaymentDate 
from 
rptPayment P 
inner join vwQry_xhsEntity_Base E on P.HolderHistoryID = E.HistoryID 
inner join LicenceType LT on P.LicenceTypeID=LT.LicenceTypeID 
inner join LicenceFeeType FT on P.FeeTypeID=FT.FeeTypeID 
inner join PaymentStatusType PT on P.PaymentStatusID = PT.PaymentStatusID 
inner join 
    (SELECT LFP.LicenseID 
     , FirstPaymentDate = MIN(LP.DatetimeStamp) 
     , LastPaymentDate = MAX(LP.DatetimeStamp) 
    FROM licenceFeePayment LFP 
    INNER JOIN licencePayment LP 
     on LFP.paymentID = LP.paymentID 
    GROUP BY lfp.LicenseID) Payment 
    ON P.licenceID = Payment.licenceID 
union ALL 
select 
P.*, 
LT.LicenceTypeDesc, FT.FeeTypeDesc, FT.ThroughputText, FT.Prorata as IsProrata, PT.PaymentStatusDesc, PT.IsPaid, 
E.EntityType as HolderEntityType, E.EntityTypeDesc as HolderEntityTypeDesc, E.PersonTitle, E.PersonFirstname, E.PersonSurname, 
E.OrganisationName, E.FullName as HolderFullName, 
E.MailAddress as HolderMailAddress, E.Suburb as HolderSuburb, E.State as HolderState, E.Postcode as HolderPostcode, 
E.Mobile as HolderMobile, E.Email, E.PFN as HolderPFN 
    , Payment.FirstPaymentDate 
    , Payment.LastPaymentDate 
from rptPayment P 
inner join vwQry_Entity E on P.HolderID = E.EntityID 
inner join LicenceType LT on P.LicenceTypeID=LT.LicenceTypeID 
inner join LicenceFeeType FT on P.FeeTypeID=FT.FeeTypeID 
inner join PaymentStatusType PT on P.PaymentStatusID = PT.PaymentStatusID 
inner join 
    (SELECT lfp.LicenseID 
     , FirstPaymentDate = MIN(LP.DatetimeStamp) 
     , LastPaymentDate = MAX(LP.DatetimeStamp) 
    FROM licenceFeePayment LFP 
    INNER JOIN licencePayment LP 
     on LFP.paymentID = LP.paymentID 
    GROUP BY lfp.LicenseID) Payment 
    ON P.licenceID = Payment.licenceID 
WHERE p.HolderHistoryID is null; 
0

, 당신은 UNION하지 UNION ALL 사용해야합니다.

먼저 해결해야 할 근본적인 비즈니스 문제는 최종 사용자에게 데이터를 표시하는 방법을 결정하는 것입니다 또한 What is the difference between UNION and UNION ALL?

+0

이것은 LP.DatetimeStamp가 지불간에 다른 경우 도움이되지 않습니다. 이는 필드가 다른 지불 날짜를 나타내는 경우 일 수 있습니다. –

+0

예, dateTimeStamp가 달라집니다. – Mat41