1

这种观点运作良好。它用于与 SQLServer 2008 R2 对话的报表构建向导

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) 的要求。因此,添加额外字段(LP.dateTimeStamp)和两个连接(licenceFeePayment tble 和 licencePayment tble)必然会导致结果集中出现重复。我假设是因为例如,如果许可证已在三个单独的付款中支付,它将在 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

帮助将不胜感激。如何加入这两个表并避免重复?

正如@registered 用户指出的那样,虽然我已经这样做了,但它并不像从我的 UNION 中删除 ALL 那样简单。

@注册用户感谢您的有用回复。根据您的帮助,我对查询进行了更改,现在还有一个小问题。我添加了一个名为“PaymentTypeDesc”的字段,它来自“paymentType”表。由于该表通过“LicencePayment”连接,因此我必须将其放在您的子查询中。我仍然收到一些重复,因为我现在相信,不仅可以为许可证支付多次付款,它们还可以来自多个不同的来源,例如 EFTPOS、CASH 等....

我如何才能同时满足多种支付交易和多种支付类型?这是我在使用您的帮助后更改的工作查询:

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
4

2 回答 2

1

您首先需要解决的基本业务问题是确定您希望如何将数据呈现给最终用户。在 LastPaymentDate 的情况下,您基本上决定最后一个 DatetimeStamp 是获胜记录。这条记录是通过使用最简单的方法选取的:子查询中列的最大值。如果您有多种付款类型描述、付款来源或其他付款方式属性,则您需要选择一个获胜者或将这些值汇总在一起。这为您提供了多种选择:

  1. 如果您只想要最后一次付款的属性,那么您可以使用 ROW_NUMBER() 聚合窗口函数,然后将您的联接限制到最后一行的数据。对于非常大的数据集,这可能会很昂贵,但是您可以在事务系统本身中分配值,也可以在一般 ETL 过程中的部分数据集上分配值。如果数据集相对较小,则成本可能微不足道。

  2. 如果每个表中都有可靠的最后修改日期,您可以运行子查询以返回最大的最后修改日期并过滤到满足此条件的行。如果多行具有相同的上次修改日期,这种方法也可能表现不佳并且可能效果不佳,那么您仍然可能返回多行。

  3. 您可以将所有选定的付款方式、来源或其他属性连接到一个字段中。这通常是一个糟糕的解决方案,因为用户可能需要分离出这些值,但在某些情况下,这正是正确的解决方案。您需要与企业主合作以确定这是否是正确的解决方案。

  4. 您可以与请求此数据的企业主交谈,并解释数据的工作原理以及您如何向他们提供数据的可能排列方式。一些用户可能需要最后的付款属性,一些可能需要连接数据,一些可能需要整个历史记录,这意味着您可能需要提供单独的非汇总付款详细信息报告。我建议在做出假设、编码您的解决方案并发现您需要重新编码整个解决方案之前与利益相关者一起审查这一点,因为它不符合业务需求。

以下是原始回复

如果 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;
于 2013-05-27T01:34:35.617 回答
0

正如肯指出的那样,您必须使用UNION,而不是UNION ALL

另请参阅UNION 和 UNION ALL 之间的区别是什么?

于 2013-05-27T01:29:20.563 回答