Wir haben 12 Arten von Ausgaben in unserer Datenbank, einige haben ziemlich unterschiedliche Daten abzüglich der Betragsfelder. Wir haben mehrere Stellen in der Anwendung und in den Berichten, die einzelne und mehrere Aufwandsummen und Zählungen pro Aufwandsart und Gesamtsummen erfordern. Am Ende möchten wir eine Ansicht für alle diese Aufrufe, können jedoch eine gespeicherte Prozedur verwenden.
Wir haben uns dafür mehrere Alternativen angesehen und festgestellt, dass ein CTE es uns ermöglicht, alle erforderlichen Daten ohne Verwendung von temporären Tabellen abzurufen. Die Verwendung von Joins funktioniert nicht, da wir gesehen haben, dass Datensätze repliziert oder entfernt wurden, unabhängig davon, was wir versucht haben.
Ich habe eine Teilmenge der Kostentabellen und der Abfrage angehängt, die den CTE enthält. Hat jemand eine bessere Alternative als diese? Etwas schneller? Nähern wir uns dieser "Abflachung" angemessen?
Bitte beachten Sie, dass der Ausführungsplan für diese Abfrage gleich ist, unabhängig davon, ob es sich um eine Ansicht oder einen Proc handelt. Die Ausführung des Proc scheint doppelt so lange zu dauern.
Unten ist der Code
WITH pe AS
(
SELECT
EventRegistrationId
,sum(AmountPaid) as AmountPaidTotal
,sum(CommercialValueAmount) as CommercialValueAmountTotal
,count(1) as ExpenseCount
FROM PettyExpenses
WHERE IsDisputed = 0 AND IsUndisputed = 0
group by EventRegistrationId
),hpe AS
(
SELECT
EventRegistrationId
,sum(AmountPaid) as AmountPaidTotal
,sum(CommercialValueAmount) as CommercialValueAmountTotal
,count(1) as ExpenseCount
FROM HirePremisesExpenses
WHERE IsDisputed = 0 AND IsUndisputed = 0
group by EventRegistrationId
), ae AS
(
SELECT
EventRegistrationId
,sum(AmountPaid) as AmountPaidTotal
,sum(CommercialValueAmount) as CommercialValueAmountTotal
,count(1) as ExpenseCount
FROM AdvertisingExpenses
WHERE IsDisputed = 0 AND IsUndisputed = 0
group by EventRegistrationId
), se AS
(
SELECT
EventRegistrationId
,sum(AmountPaid) as AmountPaidTotal
,sum(CommercialValueAmount) as CommercialValueAmountTotal
,count(1) as ExpenseCount
FROM ServiceExpenses
WHERE IsDisputed = 0 AND IsUndisputed = 0
group by EventRegistrationId
), gse AS
(
SELECT
EventRegistrationId
,sum(AmountPaid) as AmountPaidTotal
,sum(CommercialValueAmount) as CommercialValueAmountTotal
,count(1) as ExpenseCount
FROM GoodsSuppliedExpenses
WHERE IsDisputed = 0 AND IsUndisputed = 0
group by EventRegistrationId
), thve AS
(
SELECT
EventRegistrationId
,sum(AmountPaid) as AmountPaidTotal
,sum(CommercialValueAmount) as CommercialValueAmountTotal
,count(1) as ExpenseCount
FROM TravelHireVehicleExpenses
WHERE IsDisputed = 0 AND
IsUndisputed = 0
group by EventRegistrationId
)
select
distinct eer.EventRegistrationId
--Petty Expense
,ISNULL(pe.AmountPaidTotal,0) as PettyExpenseAmountPaid
,ISNULL(pe.CommercialValueAmountTotal,0) as PettyExpenseCommercial
,ISNULL(pe.ExpenseCount,0) as PettyExpenseCount
--Hire On Premise Expense
,ISNULL(hpe.AmountPaidTotal,0) as HireOnPremisesExpenseAmountPaid
,ISNULL(hpe.CommercialValueAmountTotal,0) as HireOnPremisesExpenseCommercial
,ISNULL(hpe.ExpenseCount,0) as HireOnPremisesExpenseCount
--Advertising Expense
,ISNULL(ae.AmountPaidTotal,0) as AdvertisingExpenseAmountPaid
,ISNULL(ae.CommercialValueAmountTotal,0) as AdvertisingExpenseCommercial
,ISNULL(ae.ExpenseCount,0) as AdvertisingExpenseExpenseCount
--Services Expense
,ISNULL(se.AmountPaidTotal,0) as ServiceExpenseAmountPaid
,ISNULL(se.CommercialValueAmountTotal,0) as ServiceExpenseCommercial
,ISNULL(se.ExpenseCount,0) as ServiceExpenseExpenseCount
--Goods Supplied Expense
,ISNULL(gse.AmountPaidTotal,0) as GoodsSuppliedExpenseAmountPaid
,ISNULL(gse.CommercialValueAmountTotal,0) as GoodsSuppliedExpenseCommercial
,ISNULL(gse.ExpenseCount,0) as GoodsSuppliedExpenseExpenseCount
--Travel and Vehicle Expense
,ISNULL(thve.AmountPaidTotal,0) as TravelVehicleExpenseAmountPaid
,ISNULL(thve.CommercialValueAmountTotal,0) as TravelVehicleExpenseCommercial
,ISNULL(thve.ExpenseCount,0) as TravelVehicleExpenseExpenseCount
--All Expenses
,ISNULL(pe.AmountPaidTotal,0)
+ ISNULL(hpe.AmountPaidTotal,0)
+ ISNULL(ae.AmountPaidTotal,0)
+ ISNULL(se.AmountPaidTotal,0)
+ ISNULL(gse.AmountPaidTotal,0)
+ ISNULL(thve.AmountPaidTotal,0) as AllExpenseAmountPaidTotal
,ISNULL(pe.CommercialValueAmountTotal,0)
+ ISNULL(hpe.CommercialValueAmountTotal,0)
+ ISNULL(ae.CommercialValueAmountTotal,0)
+ ISNULL(se.CommercialValueAmountTotal,0)
+ ISNULL(gse.CommercialValueAmountTotal,0)
+ ISNULL(thve.CommercialValueAmountTotal,0) as AllExpenseCommercialValueTotal
,ISNULL(pe.ExpenseCount,0)
+ ISNULL(hpe.ExpenseCount,0)
+ ISNULL(ae.ExpenseCount,0)
+ ISNULL(se.ExpenseCount,0)
+ ISNULL(gse.ExpenseCount,0)
+ ISNULL(thve.ExpenseCount,0) as AllExpenseCount
from EventRegistrations eer
left join pe on pe.EventRegistrationId = eer.EventRegistrationId
left join hpe on hpe.EventRegistrationId = eer.EventRegistrationId
left join ae on ae.EventRegistrationId = eer.EventRegistrationId
left join se on se.EventRegistrationId = eer.EventRegistrationId
left join gse on gse.EventRegistrationId = eer.EventRegistrationId
left join thve on thve.EventRegistrationId = eer.EventRegistrationId
AKTUALISIEREN:
Hier ist das Datenbankschema mit Einfügungen für diejenigen, die daran interessiert sind, es live zu sehen.
Mit SQL Server 2014 Standard habe ich das Datenbankschema / die Einfügungen in eine Datei (hier zu groß) geändert, die mehr Einfügungen sowie einen hochgeladenen Ausführungsplan und Ergebnisse enthält (2 Bilder werden nebeneinander angezeigt, um alle zurückgegebenen Spalten anzuzeigen).
quelle