Solved

Multiple aggregations in a single result set.

Posted on 2008-06-10
8
218 Views
Last Modified: 2012-05-05
Hi.

I'm in the process of converting a series of reports from Sage Retrieve 4GL to MSSQL/Crystal.

The reports in Sage are built by code (i.e. read a row from the table, add values to temporary storage/totals), rather than SQL (the 4GL db is NOT SQL).

Here are the tables in use.

Head Offices (HO.Code, HO.Name)
Customers (CU.Code, CU.Name, CU.HOCode) CU.HOCode links to HO.Code

Banks (PB.Code, PB.Period) PB.Code links to CU.Code

Tickets (CT.Ticket, CT.Period, CT.Code) CT.Period links to PB.Period and CT.Code links to CU.Code
TicketCasings (TC.Ticket, TC.Casing, TC.Grade) TC.Ticket links to CT.Ticket, TC.Grade links to lookup GR.Grade

Grade (GR.Grade, GR.Summary)

Orders (BO.Order, BO.Period, BO.Code) BO.Period links to PB.Period and BO.Code links to BO.Code
OrderCasings(BOC.Order, BOC.Casing) BOC.Order links to BO.Order


The problem I am having is trying to get SUM()s across 2 different streams. I don't think it is possible.

If it makes any sense, here is the stored procedure I'm using.

The ticket totals are all correct, but the order totals are all wrong.


I think I need to use a temp table and populate it just like I do in the 4GL code.

Or at least use a subselect for the ticket totals. Hmmm.

Any ideas?

Richard.
CREATE PROCEDURE [dbo].[raq_SingleCustomerSterlingBankReport] 

	@Year int,

	@Month int,

	@Customer CHAR(15)

AS
 

DECLARE @Period INT
 

SELECT @Period = (@Year - 1900) * 12 + @Month
 

SELECT

	-- Head Office

	LTRIM(RTRIM(HO.CustomerCode)) AS [Head Office Code], HO.Name AS [Head Office], HO.AddressLines_1 AS [Head Office Address Line 1], HO.AddressLines_2 AS [Head Office Address Line 2], HO.AddressLines_3 AS [Head Office Address Line 3], HO.AddressLines_4 AS [Head Office Address Line 4], HO.Postcode AS [Head Office Postcode], HO.Telephone AS [Head Office Telephone], HO.Facsimile AS [Head Office Fax],
 

	-- Customer

	LTRIM(RTRIM(CU.CustomerCode)) AS [Customer Code], CU.Name AS [Customer], CU.AddressLines_1 AS [Customer Address Line 1], CU.AddressLines_2 AS [Customer Address Line 2], CU.AddressLines_3 AS [Customer Address Line 3], CU.AddressLines_4 AS [Customer Address Line 4], CU.Postcode AS [Customer Postcode], CU.Telephone AS [Customer Telephone], CU.Facsimile AS [Customer Fax],
 

	-- Period Bank Totals

	PB.Period, PB.BankClosedOn, PB.Accepted, PB.Ordered, PB.Purchased,

	PB.SterlingAdjustments, PB.SterlingClose, PB.SterlingMovement, PB.SterlingOpen, PB.SterlingOrders, PB.SterlingPayments, PB.SterlingScrap, PB.SterlingTickets,

	PB.UnitsAccepted, PB.UnitsAdjust, PB.UnitsClose, PB.UnitsCollected, PB.UnitsOpen, PB.UnitsRejected, PB.UnitsSupplied, PB.UnitsValueAccepted, PB.UnitsValueAdjust, PB.UnitsValueClose, PB.UnitsValueOpen, PB.UnitsValueRejected, PB.UnitsValueSupplied,
 

	-- Shared Casing Size Code

	ISNULL(BOC.CasingSizeCode, TC.CasingSizeCode) AS 'CasingSizeCode',
 

	-- Collection Tickets

	CT.TicketNumber,

	COUNT(TC.UniqueID) AS [Casings Collected],

	SUM(CASE WHEN ISNULL(AC.SummaryCode, '') = 'P' THEN 1		ELSE 0 END) AS [Premium Qty Accepted],

	SUM(CASE WHEN ISNULL(AC.SummaryCode, '') = 'P' THEN TC.Price	ELSE 0 END) AS [Premium Value Accepted],

	SUM(CASE WHEN ISNULL(AC.SummaryCode, '') = 'S' THEN 1		ELSE 0 END) AS [Standard Qty Accepted],

	SUM(CASE WHEN ISNULL(AC.SummaryCode, '') = 'S' THEN TC.Price	ELSE 0 END) AS [Standard Value Accepted],

	SUM(CASE WHEN ISNULL(AC.SummaryCode, '') = 'E' THEN 1		ELSE 0 END) AS [Euromould Qty Accepted],

	SUM(CASE WHEN ISNULL(AC.SummaryCode, '') = 'E' THEN TC.Price	ELSE 0 END) AS [Euromould Value Accepted],

	SUM(CASE WHEN ISNULL(TC.RejectCode, '') <> '' THEN 1		ELSE 0 END) AS [Rejected Qty],

	SUM(CASE WHEN ISNULL(TC.RejectCode, '') <> '' THEN - TC.Price	ELSE 0 END) AS [Rejected Value],
 

	-- Bank Orders

	COUNT(BOC.UniqueID) AS [Casings Supplied],

	SUM(CASE WHEN ISNULL(BOC.Grade, '') = 'P' THEN BOC.SuppliedFromStock	ELSE 0 END) AS [Premium Qty Supplied],

	SUM(CASE WHEN ISNULL(BOC.Grade, '') = 'P' THEN BOC.Value			ELSE 0 END) AS [Premium Value Supplied],

	SUM(CASE WHEN ISNULL(BOC.Grade, '') = 'S' THEN BOC.SuppliedFromStock	ELSE 0 END) AS [Standard Qty Supplied],

	SUM(CASE WHEN ISNULL(BOC.Grade, '') = 'S' THEN BOC.Value			ELSE 0 END) AS [Standard Value Supplied],

	SUM(CASE WHEN ISNULL(BOC.Grade, '') = 'E' THEN BOC.SuppliedFromStock	ELSE 0 END) AS [Euromould Qty Supplied],

	SUM(CASE WHEN ISNULL(BOC.Grade, '') = 'E' THEN BOC.Value			ELSE 0 END) AS [Euromould Value Supplied]
 

FROM

	-- Head Office / Customers

	(

		Customers HO

		INNER JOIN

		Customers CU

			ON

				HO.HeadOfficeFlag = 1 -- Is a Head Office

				AND

				CU.ShortName <> 'CLOSED' -- Is not closed

				AND

				CU.PayFrequency <> 6 -- Is not daily clearance

				AND

					(

					CU.Bank = 2 -- Sterling Bank

					OR

					CU.Bank = 4 -- Mixed Bank

					)

				AND

				HO.CustomerCode = CU.HeadOfficeCode

				AND

				CU.CustomerCode = @Customer

	)
 

	-- Period Bank Totals

	LEFT OUTER JOIN
 

	PeriodBanks PB

		ON

			PB.CustomerCode = CU.CustomerCode

			AND

			PB.Period = @Period
 

	-- Merged Orders and Tickets

	LEFT OUTER JOIN
 

	(

		(

			BankOrders BO

			INNER JOIN

			BankOrdersCasings BOC

				ON

					BO.UniqueID = BOC.ParentID

					AND

					BO.OrderPeriod = @Period

		)
 

		FULL OUTER JOIN
 

		(

			CollectionTickets CT

			INNER JOIN

			TicketCasings TC

				ON

					CT.TicketStatus = 11 -- Comleted Ticket

					AND

					CT.HandledAsScrap <> 1 -- Not a scrap ticket

					AND

					CT.UniqueID = TC.ParentID

					AND

					TC.IOCCode <> 'N' -- Casing was received

					AND

					TC.CasingBank <> 1 -- Casing was not unit bank (mixed bank only)

					AND

					CT.TicketPeriod = @Period

			LEFT OUTER JOIN

			AcceptanceCodes AC

				ON

					TC.AcceptCode = AC.AcceptCode

		)

			ON

				BO.CustomerCode = CT.CustomerCode

				AND

				BO.OrderPeriod = CT.TicketPeriod

				AND

				BOC.CasingSizeCode = TC.CasingSizeCode

	)

		ON

			CU.CustomerCode = ISNULL(BO.CustomerCode, CT.CustomerCode)

--			AND

--			PB.Period = ISNULL(BO.OrderPeriod, CT.TicketPeriod)
 

GROUP BY

	CU.CustomerCode, CU.AddressLines_1, CU.AddressLines_2, CU.AddressLines_3, CU.AddressLines_4, CU.CustomerCode, CU.Facsimile, CU.Name, CU.Postcode, CU.Telephone,

	HO.CustomerCode, HO.AddressLines_1, HO.AddressLines_2, HO.AddressLines_3, HO.AddressLines_4, HO.CustomerCode, HO.Facsimile, HO.Name, HO.Postcode, HO.Telephone,

	PB.Accepted, PB.BankClosedOn, PB.Ordered, PB.Period, PB.Purchased,

	PB.SterlingAdjustments, PB.SterlingClose, PB.SterlingMovement, PB.SterlingOpen, PB.SterlingOrders, PB.SterlingPayments, PB.SterlingScrap, PB.SterlingTickets,

	PB.UnitsAccepted, PB.UnitsAdjust, PB.UnitsClose, PB.UnitsCollected, PB.UnitsOpen, PB.UnitsRejected, PB.UnitsSupplied, PB.UnitsValueAccepted, PB.UnitsValueAdjust, PB.UnitsValueClose, PB.UnitsValueOpen, PB.UnitsValueRejected, PB.UnitsValueSupplied,

	CT.TicketNumber,

	TC.CasingSizeCode,

	BOC.CasingSizeCode
 

ORDER BY

	CasingSizeCode,

	TicketNumber

GO

Open in new window

0
Comment
Question by:RQuadling
  • 2
  • 2
8 Comments
 
LVL 8

Accepted Solution

by:
srnar earned 250 total points
ID: 21750638
Uf, it is long script. Can you post "create table" and some data to be popultated (via insert). Then we can be more helpful on samples. If not you can try to use windowing aggregation functions that can help with sorting e.g. RANK, ROW_ID. See this link

http://msdn.microsoft.com/en-us/library/ms189798.aspx
0
 
LVL 17

Assisted Solution

by:MIKE
MIKE earned 250 total points
ID: 21752164
"...The problem I am having is trying to get SUM()s across 2 different streams. I don't think it is possible.
..."

If I'm understanding your requirement.....you should be able to do "sum across 2 different streams" in "Crystal" by the use of VARIABLES after data is populated into the report from your stored procedure.

 M
0
 
LVL 40

Author Comment

by:RQuadling
ID: 21752939
For what it is worth, I fixed it.

I was trying to sum AND merge data at the same time.

I actually wanted to merge pre-summed data.

Here is the working stored procedure.

Thanks for looking.


CREATE PROCEDURE [dbo].[raq_SingleCustomerSterlingBankReport] 

	@Year int,

	@Month int,

	@Customer CHAR(15)

AS
 

DECLARE @Period INT
 

SELECT @Period = (@Year - 1900) * 12 + @Month
 

SELECT DISTINCT

	-- Head Office

	LTRIM(RTRIM(HO.CustomerCode)) AS [Head Office Code], HO.Name AS [Head Office], 

	HO.AddressLines_1 AS [Head Office Address Line 1], HO.AddressLines_2 AS [Head Office Address Line 2], HO.AddressLines_3 AS [Head Office Address Line 3], HO.AddressLines_4 AS [Head Office Address Line 4], 

	HO.Postcode AS [Head Office Postcode], HO.Telephone AS [Head Office Telephone], HO.Facsimile AS [Head Office Fax],
 

	-- Customer

	LTRIM(RTRIM(CU.CustomerCode)) AS [Customer Code], CU.Name AS [Customer], 

	CU.AddressLines_1 AS [Customer Address Line 1], CU.AddressLines_2 AS [Customer Address Line 2], CU.AddressLines_3 AS [Customer Address Line 3], CU.AddressLines_4 AS [Customer Address Line 4], 

	CU.Postcode AS [Customer Postcode], CU.Telephone AS [Customer Telephone], CU.Facsimile AS [Customer Fax],
 

	-- Period Bank Totals

	PB.Period, PB.BankClosedOn, PB.Accepted, PB.Ordered, PB.Purchased,

	PB.SterlingAdjustments, PB.SterlingClose, PB.SterlingMovement, PB.SterlingOpen, PB.SterlingOrders, PB.SterlingPayments, PB.SterlingScrap, PB.SterlingTickets,

	PB.UnitsAccepted, PB.UnitsAdjust, PB.UnitsClose, PB.UnitsCollected, PB.UnitsOpen, PB.UnitsRejected, PB.UnitsSupplied, 

	PB.UnitsValueAccepted, PB.UnitsValueAdjust, PB.UnitsValueClose, PB.UnitsValueOpen, PB.UnitsValueRejected, PB.UnitsValueSupplied,
 

	-- Shared Casing Size Code

	Casings.CasingSizeCode,

	CTS.*,

	BOS.*
 

FROM

	(

		(

		-- Head Office / Customers

			(

			Customers HO 

			INNER JOIN 

			Customers CU 

				ON 

					HO.HeadOfficeFlag = 1 

					AND 

					CU.ShortName <> 'CLOSED' 

					AND 

					CU.PayFrequency <> 6 

					AND 

						(

						CU.Bank = 2 

						OR 

						CU.Bank = 4

						) 

					AND 

					HO.CustomerCode = CU.HeadOfficeCode 

					AND 

					CU.CustomerCode = @Customer

			)
 

		LEFT OUTER JOIN 
 

		-- Period Bank Totals

		PeriodBanks PB 

			ON 

				PB.CustomerCode = CU.CustomerCode 

				AND 

				PB.Period = @Period

		)
 

		LEFT OUTER JOIN

			(

			SELECT 

				ISNULL(BO.OrderPeriod, CT.TicketPeriod) AS Period, 

				ISNULL(BO.CustomerCode, CT.CustomerCode) AS CustomerCode, 

				ISNULL(BOC.CasingSizeCode, TC.CasingSizeCode) AS CasingSizeCode

			FROM

				(

				BankOrders BO 

				INNER JOIN 

				BankOrdersCasings BOC 

					ON 

						BO.UniqueID = BOC.ParentID 

						AND 

						BO.OrderPeriod = @Period 

						AND 

						BO.CustomerCode = @Customer

				)
 

				FULL OUTER JOIN
 

				(

				CollectionTickets CT 

				INNER JOIN 

				TicketCasings TC 

					ON 

						CT.TicketStatus = 11 

						AND 

						CT.HandledAsScrap <> 1 

						AND 

						CT.UniqueID = TC.ParentID 

						AND 

						TC.IOCCode <> 'N' 

						AND 

						TC.CasingBank <> 1 

						AND 

						CT.TicketPeriod = @Period 

						AND 

						CT.CustomerCode = @Customer

				)

				ON 

					BO.CustomerCode = CT.CustomerCode 

					AND 

					BO.OrderPeriod = CT.TicketPeriod 

					AND 

					BOC.CasingSizeCode = TC.CasingSizeCode

			) Casings 

			ON 

				CU.CustomerCode = Casings.CustomerCode 

				AND 

				PB.Period = Casings.Period

	)
 

	LEFT OUTER JOIN
 

	(

	SELECT

		BOC.CasingSizeCode AS 'BankCasingSizeCode',

		SUM(CASE WHEN ISNULL(BOC.Grade, '') = 'P' THEN BOC.SuppliedFromStock	ELSE 0 END) AS [Premium Qty Supplied],

		SUM(CASE WHEN ISNULL(BOC.Grade, '') = 'P' THEN BOC.Value		ELSE 0 END) AS [Premium Value Supplied],

		SUM(CASE WHEN ISNULL(BOC.Grade, '') = 'S' THEN BOC.SuppliedFromStock	ELSE 0 END) AS [Standard Qty Supplied],

		SUM(CASE WHEN ISNULL(BOC.Grade, '') = 'S' THEN BOC.Value		ELSE 0 END) AS [Standard Value Supplied],

		SUM(CASE WHEN ISNULL(BOC.Grade, '') = 'E' THEN BOC.SuppliedFromStock	ELSE 0 END) AS [Euromould Qty Supplied],

		SUM(CASE WHEN ISNULL(BOC.Grade, '') = 'E' THEN BOC.Value		ELSE 0 END) AS [Euromould Value Supplied]

	FROM

		BankOrders BO 

		INNER JOIN 

		BankOrdersCasings BOC 

			ON 

				BO.UniqueID = BOC.ParentID 

				AND 

				BO.OrderPeriod = @Period 

				AND 

				BO.CustomerCode = @Customer

	GROUP BY

		BOC.CasingSizeCode

	) AS BOS 

		ON 

			BOS.BankCasingSizeCode = Casings.CasingSizeCode
 

	LEFT OUTER JOIN
 

	(

	SELECT

		TC.CasingSizeCode AS 'TicketCasingSizeCode',

		CT.TicketNumber,

		COUNT(TC.UniqueID) AS [Casings Collected],

		SUM(CASE WHEN ISNULL(AC.SummaryCode, '') = 'P' THEN 1		ELSE 0 END) AS [Premium Qty Accepted],

		SUM(CASE WHEN ISNULL(AC.SummaryCode, '') = 'P' THEN TC.Price	ELSE 0 END) AS [Premium Value Accepted],

		SUM(CASE WHEN ISNULL(AC.SummaryCode, '') = 'S' THEN 1		ELSE 0 END) AS [Standard Qty Accepted],

		SUM(CASE WHEN ISNULL(AC.SummaryCode, '') = 'S' THEN TC.Price	ELSE 0 END) AS [Standard Value Accepted],

		SUM(CASE WHEN ISNULL(AC.SummaryCode, '') = 'E' THEN 1		ELSE 0 END) AS [Euromould Qty Accepted],

		SUM(CASE WHEN ISNULL(AC.SummaryCode, '') = 'E' THEN TC.Price	ELSE 0 END) AS [Euromould Value Accepted],

		SUM(CASE WHEN ISNULL(TC.RejectCode, '') <> '' THEN 1		ELSE 0 END) AS [Rejected Qty],

		SUM(CASE WHEN ISNULL(TC.RejectCode, '') <> '' THEN - TC.Price	ELSE 0 END) AS [Rejected Value]

	FROM

		CollectionTickets CT

		INNER JOIN

		TicketCasings TC

			ON

				CT.TicketStatus = 11 -- Comleted Ticket

				AND

				CT.HandledAsScrap <> 1 -- Not a scrap ticket

				AND

				CT.UniqueID = TC.ParentID

				AND

				TC.IOCCode <> 'N' -- Casing was received

				AND

				TC.CasingBank <> 1 -- Casing was not unit bank (mixed bank only)

				AND

				CT.TicketPeriod = @Period

				AND

				CT.CustomerCode = @Customer

		LEFT OUTER JOIN

		AcceptanceCodes AC

			ON

				TC.AcceptCode = AC.AcceptCode

	GROUP BY

		TC.CasingSizeCode,

		CT.TicketNumber		

	) AS CTS 

		ON 

			CTS.TicketCasingSizeCode = Casings.CasingSizeCode

ORDER BY

	CasingSizeCode,

	TicketNumber

GO

Open in new window

0
 
LVL 17

Expert Comment

by:MIKE
ID: 21753731
Glad you were able to get it working....

  : )
0
 
LVL 40

Author Comment

by:RQuadling
ID: 21755811
The original 4gl app has no SQL. Instead, I had to use a temp table to gather all the data for the reporting. This takes around 10 mins.

With the new SQL db and the above SP, I can get the whole job done in under 60 seconds. And that includes using PHP to talk to Crystal Reports to produce PDF documents!

These last 2 weeks have given me a new lease of life with Crystal. I'm getting to like it.
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Introduction: When running hybrid database environments, you often need to query some data from a remote db of any type, while being connected to your MS SQL Server database. Problems start when you try to combine that with some "user input" pass…
Occasionally there is a need to clean table columns, especially if you have inherited legacy data. There are obviously many ways to accomplish that, including elaborate UPDATE queries with anywhere from one to numerous REPLACE functions (even within…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now