此观点运作良好。它用于与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那么简单。
@registered用户感谢您的回复。我已根据您的帮助对我的查询进行了更改,现在又有了一个小问题。我添加了一个名为'PaymentTypeDesc'的字段,该字段来自'paymentType'表。由于此表通过'LicencePayment'加入,我必须将它放在您的子查询中。我仍然得到一些重复,因为我现在相信,不仅可以多次支付许可证,它们可以来自多个不同来源EG 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
答案 0 :(得分:1)
首先需要解决的基本业务问题是确定如何向最终用户提供数据。在LastPaymentDate的情况下,您基本上决定最后一个DatetimeStamp是获胜记录。使用最简单的方法选择此记录:子查询中列的最大值。如果您有多种付款类型说明,付款来源或其他付款方式属性,则您需要选择一个赢家或将这些值汇总在一起。这为您提供了几个选项:
如果您只需要上次付款的属性,则可以使用ROW_NUMBER()聚合窗口函数,然后将您的联接限制为最后一行的数据。对于非常大的数据集,这可能很昂贵,但您可以在事务系统本身或在一般ETL过程中的部分数据集上分配值。如果数据集相对较小,则成本可能微不足道。
如果每个表中都有可靠的上次修改日期,则可以运行子查询以返回上次修改的最大日期,并过滤到满足此条件的行。如果多行具有相同的最后修改日期,这种方法也可能表现不佳,也可能无法正常工作,那么您仍可能返回多行。
您可以将所有选定的付款方式,来源或其他属性连接到一个字段中。这通常是一个很差的解决方案,因为用户可能需要分离出的值,但在某些情况下,这是正确的解决方案。您需要与业务所有者一起确定这是否是正确的解决方案。
您可以与请求此数据的企业主交谈,并说明数据的工作原理以及如何为他们提供数据的可能排列方式。一些用户可能想要最后的支付属性,一些用户可能想要连接数据,一些用户可能想要整个历史记录,这意味着您可能需要提供单独的非聚合支付详细信息报告。我建议在做出假设,编写解决方案以及发现需要重新编码整个解决方案之前与利益相关方进行审核,因为它不符合业务需求。
以下的原始回复
如果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;
答案 1 :(得分:0)
正如肯指出,你必须使用UNION
,而不是UNION ALL
。