Grouping ignoring blank fields - sql

I am having a hard time to identify (and fix) the grouping issue I have with the following query. My data has some Country fields blank and the query is ignoring them, only those with non blank values are converted to rows. I tried removing the country grouping but I get the error "You tried to execute a query that does not include the specified expression "Country" as part of an aggregate function". This is the query I have in Access:
TRANSFORM Count([passed courses].[Course Number])
SELECT [domain].[Account ID], [domain].[Account Name], [passed courses].[Learner Email Address], [passed courses].Category, [passed courses].Country, [passed courses].[Earliest Start_Date], [passed courses].[Latest End_Date]
FROM [Domain Master] AS [domain] INNER JOIN (SELECT d3.ID, d3.[Learner Email Address], d3.[Course Number], d3.[Transcript Status], d3.Domain, c2.Category, [passed levels].Country, [passed levels].[Earliest Start_Date], [passed levels].[Latest End_Date]
FROM
(SELECT [completed courses].[Learner Email Address], [completed courses].[Level], [completed courses].Category, [completed courses].[Completed Count], [completed courses].Country, [learner dates].[Earliest Start_Date], [learner dates].[Latest End_Date]
FROM
(SELECT [courses taken].[Learner Email Address], [courses taken].[Level], [courses taken].Category, Count([courses taken].ID) AS [Completed Count], [courses taken].Country
FROM
(SELECT d1.ID, d1.[Learner Email Address], d1.[Course Number], c1.[Level], c1.Category, d1.[Transcript Status], d1.Country
FROM [Data] AS d1
INNER JOIN [Courses] AS c1 ON d1.[Course Number] = c1.[Course Number]
)
AS [courses taken]
WHERE [courses taken].[Transcript Status] = "Completed"
GROUP BY [courses taken].[Learner Email Address], [courses taken].Level, [courses taken].Category, d1.Country
)
AS [completed courses]
INNER JOIN
(SELECT d2.[Learner Email Address], d2.Country, Min(d2.Start_Date) AS [Earliest Start_Date], Max(d2.End_Date) AS [Latest End_Date]
FROM [Data] AS d2
GROUP BY d2.[Learner Email Address], d2.Country
) AS [learner dates]
ON [completed courses].[Learner Email Address] = [learner dates].[Learner Email Address] AND
[completed courses].Country = [learner dates].Country
WHERE
([courses taken].Category = 'Sales') AND (
(([completed courses].Level = 1) AND ([completed courses].[Completed Count] >=5)) OR
(([completed courses].Level = 2) AND ([completed courses].[Completed Count] >=5)) OR
(([completed courses].Level = 3) AND ([completed courses].[Completed Count] >=1))
) OR
([courses taken].Category = 'Purchase') AND (
(([completed courses].Level = 1) AND ([completed courses].[Completed Count] >=5)) OR
(([completed courses].Level = 2) AND ([completed courses].[Completed Count] >=4)) OR
(([completed courses].Level = 3) AND ([completed courses].[Completed Count] >=1))
)
)
AS [passed levels]
INNER JOIN ([Data] AS d3 INNER JOIN Courses AS c2 ON ((d3.[Course Number] = c2.[Course Number])))
ON ([passed levels].Level = c2.Level) AND ([passed levels].[Learner Email Address] = d3.[Learner Email Address]) AND ([passed levels].Category = c2.Category)
) AS [passed courses] ON [domain].[Partner Domain] = [passed courses].Domain
GROUP BY [domain].[Account ID], [domain].[Account Name], [passed courses].[Learner Email Address], [passed courses].Category, [passed courses].Country, [passed courses].[Earliest Start_Date], [passed courses].[Latest End_Date]
PIVOT [passed courses].[Course Number];
Any help is appreciated!

What if you added a case statement into your query where if country = '' then return a unique GUID else return the Country column value and alias the case as Country
GUID function for access
You may need to wrap the whole query as a sub query to group by the Country aliased column though. This isn't tested, just a concept idea as I can't see any other way of grouping a country and ignoring blanks within the same select, or a less you did 2 selects and did a union instead.
Regards
Liam

Related

Error in SSIS Package - There is a data source column with no name

I have a straightforward SQL statement that I posted into a DataFlow Task and got this dreaded error. There is no stored procedure or temp tables involved.
What am I missing?
The SQL works fine in SSMS and returns appropriate results. The query is pretty simple and I have never seen this error in SSIS before.
select cast([CREATE_DATE] as date) as create_date
,[SALES_DOCUMENT_NUM]
,[ORDER_LINE_NUM]
,[340b_id]
,[ALT_CHAIN_ID]
,[ALT_CUSTOMER_NUM]
,[BUYING_GROUP_NUM]
,[BUYING_GROUP_NAME]
,[COID]
, chain_id
,[CHAIN_ID_DESC]
,[CITY]
,[CURRENT_GL_CODE]
,[CURRENT_GL_DESC]
, [CUSTOMER_NUM]
,[CUSTOMER_NAME]
,cast(nullif([CUSTOMER_PACK_SIZE] ,'') as numeric(18,3)) as [CUSTOMER_PACK_SIZE]
,[DEA_NUM]
,[FORMULARY_ITEMS]
,[GLN]
,[HIN_NUM]
,[HISTORICAL_GL_CODE]
,[HISTORICAL_GL_DESC]
,[STATE]
,[STORE_NUM]
,[STREET]
,[TELEPHONE]
,[ZIP_CODE]
,[ABC_NUM]
,[ABC_6]
,[ABCHUN_IN_BLUEBOOK_FORMAT]
,[ABC_SELLING_UOM]
,[AHFS_THERAPEUTIC_CLASS_CODE]
,[AHFS_THERAPEUTIC_CLASS_DESC]
,[ABBREVIATED_DESC]
,[CORPORATE_ITEM_STATUS]
,[CORPORATE_ITEM_STATUS_DESC]
,[CURR_HUN_NUMBER]
,[DEA_CLASS]
, [DIVISION_STATUS]
,cast(isnull(nullif([FDB_PACKAGE_SIZE_QTY] ,''),0) as numeric(18,3)) as [FDB_PACKAGE_SIZE_QTY]
,cast(isnull(nullif([FDB_SWP_WHOLESALE_FACTOR] ,''),0) as numeric(18,3)) as [FDB_SWP_WHOLESALE_FACTOR]
,[FINE_LINE_CLASS]
,[FINE_LINE_CLASS_DESC]
,[FORM_CODE]
,[GCN]
,[GCN_SEQ_NUM]
,[GTIN_NUM]
,[GENERIC_DESC]
,[GENERIC_EXTENDED_DESC]
,[GENERIC_ABBREV_DESC]
,[GENERIC_FULL_DESC]
,[GENERIC_HICL]
,[GENERIC_PARENT_NUM]
,[HCPCS_CODE]
,[HRI_NUM]
,[HAZARD_CODE]
,[HAZARD_CODE_DESC]
,[ITM_CAT_CD]
,[ITM_CAT_DSC]
,[NDC]
,[OMP_ITEM_FAMILY]
,[OMP_ITEM_FAMILY_DESC]
,[OMP_ITEM_INDICATOR]
,cast(isnull(nullif([PACKAGE_SWP] ,''),0) as numeric(18,3)) as [PACKAGE_SWP]
,[PRICE_STICKER_RETAIL_QTY]
,[PRIMARY_INGREDIENT_HIC4]
,[PRIMARY_INGREDIENT_HIC4_DESC]
,[PRIVATE_LABEL_INDICATOR]
,[PRODUCT_CATEGORY]
,[PRODUCT_CATEGORY_DESC]
,[PRODUCT_DESCRIPTION]
,[PRODUCT_ENTERED]
,[PRODUCT_GROUP]
,[PRODUCT_GROUP_DESC]
,[PRODUCT_PRICING_CLASS]
,cast(isnull(nullif([SIZE_QTY],''),0) as numeric(18,3)) as [SIZE_QTY]
,[SWP]
,[SWP_DATE]
,[SINGLE MULTI_SOURCE]
,cast(isnull(nullif([STANDARD_UNIT_SWP] ,''),0) as numeric(18,3)) as [STANDARD_UNIT_SWP]
,[SUPPLIER_NUM]
,[SUPPLIER_MATERIAL]
,[SUPPLIER_NAME]
,[UPC_BARCODE]
,[UNIT_DOSE_CODE]
,cast(isnull(nullif([UNIT_SIZE_QTY] ,''),0) as numeric(18,3)) as [UNIT_SIZE_QTY]
,[UNIT_STRENGTH_CODE]
,[UNIT_STRENGTH_QTY]
,[CONTRACT_NUM]
,[CONTRACT_ABBREV_NAME]
,cast(isnull(nullif([CONTRACT_COST] ,''),0) as numeric(18,3)) as [CONTRACT_COST]
,[CONTRACT_EFFECTIVE_DATE]
,[CONTRACT_EXP_DATE]
,[CONTRACT_NAME]
,[CONTRACT_SALE_FLAG]
,[CREATED_BY]
,[CREDIT_REASON_CODE]
,[CREDIT_REASON_DESC]
,cast(isnull(nullif([CURRENT_ACQ_COST] ,''),0) as numeric(18,3)) as [CURRENT_ACQ_COST]
,[CUSTOMER_DEPT_NUM]
,[CUSTOMER_ITEM_NUM]
,[CUSTOMER_PO_NUM]
,[DISTRIBUTION_CENTER]
,[DROPSHIP_FLAG]
,cast(isnull(nullif([DRUG_FORM_COST] ,''),0) as numeric(18,3)) as [DRUG_FORM_COST]
,cast(isnull(nullif([EXCEPTION_QTY] ,''),0) as numeric(18,3)) as [EXCEPTION_QTY]
,cast(isnull(nullif([EXTENDED_WHOLESALE_COST] ,''),0) as numeric(18,3)) as [EXTENDED_WHOLESALE_COST]
,[HISTORICAL_CUSTOMER_ITEM__NUM]
,[INVOICE_NUM]
,[INVOICE_DATE]
,[INVOICE_DUE_DATE]
,[INVOICE_LINE_NUM]
,[INVOICE_MONTH]
,cast(isnull(nullif([INVOICE_PRICE] ,''),0) as numeric(18,3)) as [INVOICE_PRICE]
,[INVOICE_TYPE]
,[INVOICE_TYPE_DESC]
,[INVOICE_YEAR]
,[LAST_INVOICE_NUM]
,[LAST_PURCHASE_PRICE]
,[LAST_PURCHASE_DATE]
,[NARCOTIC_BLANK_NUM]
,cast(isnull(nullif([ORDER_QTY] ,''),0) as numeric(18,3)) [ORDER_QTY]
,[ORDER_SOURCE]
,[ORDER_SOURCE_DESC]
,[ORDER_TYPE_CODE]
,[ORDER_TYPE_DESC]
,[ORIGINAL_INVOICE_NUM]
,[PRICE_METHOD]
,[PRICE_METHOD_DESC]
,[PROCUREMENT_CODE]
,[PROCUREMENT_MESSAGE]
,[PROGRAM_CODE]
,[PROGRAM_CODE_DESC]
,cast(isnull(nullif([QTY_SHIPPED] ,''),0) as numeric(18,3)) as [QTY_SHIPPED]
,[REASON_CODE]
,[REJECTION_REASON_CODE]
,[REJECTION_REASON_DESC]
,cast([SHIP_DATE] as date)
,[SPCL_HANDLING_CODE]
,[SPCL_HANDLING_CODE_DESC]
,[SUBMITTED_BY]
,[SUBSTITUTION_CODE]
,[SUBSTITUTION_CODE_DESC]
,[SUPPLIER_CONTRACT_NUM]
,cast(isnull(nullif([TAX_AMOUNT] ,''),0) as numeric(18,3)) as [TAX_AMOUNT]
,cast(isnull(nullif([TOTAL_EXTENDED_COST],''),0) as numeric(18,3)) as [TOTAL_EXTENDED_COST]
,[WAC_WITH_NET_OVERRIDE]
,cast(isnull(nullif([WHOLESALE_COST] ,''),0) as numeric(18,3)) as [WHOLESALE_COST]
,[8 BYTE MATNR]
,[NDC NUMBER]
,[ITEM STS DESCRIP]
,[MATERIAL DESCRIP]
,cast(isnull(nullif([FDB PKG SIZE] ,''),0) as numeric(18,3)) as [FDB PKG SIZE]
,[AWF SELL FACTOR]
,cast(isnull(nullif([PKG METRIC SIZE] ,''),0) as numeric(18,3)) as [PKG METRIC SIZE]
,[GCN SEQ NUMBER]
,[GNC GROUP NUMBER]
,cast(isnull(nullif([ACQUISITION COST] ,''),0) as numeric(18,3)) as [ACQUISITION COST]
,[CONTRACT NUMBER]
,[CONTRACT NAME]
,cast(isnull(nullif([ORIG CONTRACT COST] ,''),0) as numeric(18,3)) as [ORIG CONTRACT COST]
,[CONTRACT EFF DATE]
,[CONTRACT EXP DATE]
,cast(isnull(nullif([ABC WAC COST],''),0) as numeric(18,3)) as [ABC WAC COST]
,cast([ABC WAC EFF DT] as date) as [ABC WAC EFF DT]
,cast(isnull(nullif([MSRP PRICE] ,''),0) as numeric(18,3)) as [MSRP PRICE]
,cast(isnull(nullif([CSRP PRICE] ,''),0) as numeric(18,3)) as [CSRP PRICE]
,cast(isnull(nullif([RETAIL PRICE],''),0) as numeric(18,3)) as [RETAIL PRICE]
,[LEGACY ITM NBR]
from dbo.ABC_Invoice_File_Staging inv
left join dbo.ABC_Catalog_File_Staging cat on cast(inv.CUSTOMER_NUM as numeric) = cat.account_number
and inv.CREATE_DATE between cat.filedate and cat.filedate+6
and inv.NDC = cat.[NDC NUMBER]
and inv.[ABC_NUM]=cat.[8 BYTE MATNR]
where inv.CREATE_DATE = '20191015'```
no column name
CAST([SHIP_DATE] AS date)

Conversion failed when converting the varchar value 'Email' to data type int

I have a stored procedure that is getting data from some other database tables and and putting them into another table. I am running into an error
Conversion failed when converting the varchar value 'Email' to data type int.
However, I don't see where/how a data conversion would take place.
I have checked the data types for both where I am getting the email address and where I am inserting the email address. They are both set to varchar(255).
DECLARE #prefix varchar(50), #middle varchar(50), #suffix varchar(50),
#companyID int, #companyNm varchar(100),
#badge varchar(50), #title varchar(100), #salutation varchar(50),
#pplType int, #email varchar(255), #specialty int,
#mailpref int, #source int,
#add1 varchar(100), #add2 varchar(100), #city varchar(50),
#state varchar(50), #zip varchar(50), #countryID int,
#phone varchar(50), #ext varchar(50), #fax varchar(50),
#addID int, #addType int, #arrival datetime, #departure datetime,
#regType varchar(50), #mtRegID int
SELECT #regType = regType
FROM Registration
WHERE personID = #personID AND meetingCode = #meetingCode
SELECT
#prefix = [Name Prefix], #middle = Middle, #suffix = [Name Suffix],
#companyID = [Company ID], #companyNm = [Company Name],
#badge = [Badge Name], #title = Title,
#salutation = Salutation, #pplType = [People Type],
#email = Email, #specialty = [Specialty ID], #mailpref = MailPref,
#source = [Source ID]
FROM
MeetingtrakTest.dbo.tblPeople
WHERE
[Person ID] = #personID
SELECT
#add1 = Address1, #add2 = Address2, #city = City, #state = State,
#zip = Zip, #countryID = [Country Id],
#phone = Phone, #ext = Extension, #fax = Fax, #addID = [Address ID]
FROM
MeetingtrakTest.dbo.tblPeopleAddresses
WHERE
[Person ID] = #personID AND [Primary] = 1
SELECT
#arrival = [Meeting Start Date], #departure = [Meeting End Date]
FROM
MeetingtrakTest.dbo.tblMeetings
WHERE
[Meeting Code] = #meetingCode
INSERT INTO tblRegistration ([Person Id], [Pre or On-Site], [Attendee List], [Use Company Name], [Reg Date], [Use Housing Costs], [Use Itinerary Costs], Attended, [Date Entered], [Entered By], [Date Updated], [First Name], [Last Name], [Meeting Code], [Registration Code], [Name Prefix], Middle, [Name Suffix], [Company ID], [Company Name], [Badge Name], Title, Salutation, [People Type], [Email], [Specialty ID], MailPref, Source, [Address 1], [Address 2], City, State, Zip, [Country ID], Phone, Extension, Fax, [Address Id] ,[Address Type], [Arrival Date], [Departure Date])
VALUES (#personID, 1, 1, 1, GETDATE(), 0, 0, 0, GETDATE(), 'etrak', GETDATE(), #first, #last, #meetingCode, #regType, #prefix, #middle, #suffix, #companyID, #companyNm, #badge, #title, #salutation, #pplType, #email, #specialty, #mailpref, #source, #add1, #add2, #city, #state, #zip, #countryID, #phone, #ext, #fax, #addID, #addType, #arrival, #departure);
SET #mtRegID = SCOPE_IDENTITY();

concatenate columns based on blank columns

I am having three columns,- and / should be used as separator result should come in new column(File Index-sub Index/Year),if sub index is blank then result should be (File Index/Year).
SELECT
[ File Index].[File Index]
, [ File Index].[Sub Index]
, [ File Index].[Financial Year]
, [ File Index].[File Index] & [Sub Index] & [Financial Year] AS [Composite Index]
FROM [File Index];
Since you have both MySQL and MS Access listed, here are solutions for both.
For MySQL, you can use a CASE statement for this:
SELECT [File Index], [Sub Index], [Financial Year],
CASE WHEN [Sub Index] IS NOT NULL
THEN Concat([File Index], '-', [Sub Index], '/', [Financial Year])
ELSE Concat([File Index], '/', [Financial Year])
END as [Composite Index]
FROM [File Index];
For MS Access, you will use Switch(...):
SELECT [File Index], [Sub Index], [Financial Year],
Switch(Not IsNull([Sub Index]),
[File Index] & '-' & [Sub Index] & '/' & [Financial Year],
IsNull([Sub Index]),
[File Index] & '/' & [Financial Year]
) as [Composite Index]
FROM [File Index];
You can use IIF function: IIF(Condition;ConcatenationIfTrue;ConcatenationIfFalse)
SELECT
[ File Index].[File Index]
, [ File Index].[Sub Index]
, [ File Index].[Financial Year]
, IIF(ISNULL([Sub Index];[ File Index].[File Index] & "/" & [Financial Year];[ File Index].[File Index] & [Sub Index] & [Financial Year]) AS [Composite Index]
FROM [File Index];

MS ACCESS: Query Too Complex?

Here is the code that is causing the error:
SELECT [serial number], [page count], [minutes], [status], [activity], [venue short name], [assigned to], [publishing format name], [query], [photo], [notes], [tabular], [partpub], [statusdate]
FROM MyProd
WHERE ((MyProd.[Status] = [Forms]![My Prod]![StatusFilter])
OR ([Forms]![My Prod]![StatusFilter] Is Null))
AND ((myprod.[activity] = [Forms]![My Prod]![ActivityFilter])
OR ([Forms]![My Prod]![ActivityFilter] Is Null))
AND ((myprod.[activity] = [Forms]![My Prod]![ActivityFilter])
OR ([Forms]![My Prod]![ActivityFilter] Is Null))
AND ((myprod.[venue short name] Like "*" & [Forms]![my prod]![venuefilter] & "*")
OR ([Forms]![my prod]![venuefilter] Is Null))
AND ((myprod.[assigned to] = [Forms]![My Prod]![ParticipantFilter])
OR ([Forms]![My Prod]![ParticipantFilter] Is Null))
AND ((myprod.[publishing format name] = [Forms]![My Prod]![PubFilter])
OR ([Forms]![My Prod]![PubFilter] Is Null))
AND ((myprod.[query] = [Forms]![My Prod]![PubFilter])
OR ([Forms]![My Prod]![PubFilter] Is Null))
AND (iif([Forms]![My Prod]![SpecialRequestFilter]="Photo", MyProd.[Photo] Like -1, ([Forms]![My Prod]![PubFilter] Is Null)))
AND (iif([Forms]![My Prod]![SpecialRequestFilter]="Query", MyProd.[Query] Like -1, ([Forms]![My Prod]![PubFilter] Is Null)))
AND (iif([Forms]![My Prod]![SpecialRequestFilter]="Table", MyProd.[Tabular] Like -1, ([Forms]![My Prod]![PubFilter] Is Null)))
AND (iif([Forms]![My Prod]![SpecialRequestFilter]="Partial Pub", MyProd.[partpub] Like -1, ([Forms]![My Prod]![PubFilter] Is Null)))
AND (iif([Forms]![My Prod]![SpecialRequestFilter]="Has Notes", MyProd.[Notes] <> "", ([Forms]![My Prod]![PubFilter] Is Null)))
AND (IIf((([Forms]![My Prod]![SD]<>"") AND ([Forms]![My Prod]![ED]<>"")), MyProd.[statusdate] Between [Forms]![My Prod]![SD] AND [Forms]![My Prod]![ED], (MyProd.[StatusDate] Like "*" OR MyProd.[StatusDate] Is Null)))
I can't see how complex this is... Can you suggest a "simple" version of this? These are filters that when left blank the resulting query should return all. Thank you.

Add Subtotal & Total to Pivot

I have the following query
SELECT [Acct], [Customer], [Code], [Description], [Value], [Sale Person],
[Region], [Store Type], ISNULL([2016], 0) AS '2016', ISNULL([2017],0) AS
'2017'
FROM
(
SELECT CUCODE AS 'Acct', CUNAME AS 'Customer', STKCODE AS 'Code', STKNAME AS 'Description', SUM(OD_QTYORD) AS 'Packs Ordered'
, OD_GROSS AS 'Value', CUSORT AS 'Sale Person', LEFT(CUUSER1,3) AS 'Region', DATEPART(yyyy, OD_DATE) AS 'Year', OH_USER2 AS 'Store Type'
FROM STK_STOCK
INNER JOIN ORD_DETAIL ON STK_STOCK.STKCODE=ORD_DETAIL.OD_STOCK_CODE
INNER JOIN ORD_HEADER ON OD_ORDER_NUMBER=OH_ORDER_NUMBER
INNER JOIN SL_ACCOUNTS ON OH_ACCOUNT=CUCODE
WHERE STKCODE IN ('76958', '27225', '27221', '26962', '26959', '26961', '27226', '26963', '26960')
AND OD_QTYORD > 0
AND CUCODE != 'Z9997'
GROUP BY CUCODE, CUNAME, STKCODE, STKNAME, OD_GROSS, CUSORT, CUUSER1, OD_DATE, OH_USER2
) AS SourceTable
PIVOT
(
SUM([Packs Ordered])
FOR [Year] IN ([2016], [2017])
) AS PivotTable;
The output looks great but I want a subtotal for each 'Acct' and a Grand Total for the whole thing.
Can anyone help with this?
You can use group by grouping sets as below:
SELECT [Acct], [Customer], [Code], [Description], [Value], [Sale Person],
[Region], [Store Type], sum([2016]) as [2016], sum([2017]) as [2017] FROM
(
SELECT [Acct], [Customer], [Code], [Description], [Value], [Sale Person],
[Region], [Store Type], ISNULL([2016], 0) AS '2016', ISNULL([2017],0) AS
'2017'
FROM
(
SELECT CUCODE AS 'Acct', CUNAME AS 'Customer', STKCODE AS 'Code', STKNAME AS 'Description', SUM(OD_QTYORD) AS 'Packs Ordered'
, OD_GROSS AS 'Value', CUSORT AS 'Sale Person', LEFT(CUUSER1,3) AS 'Region', DATEPART(yyyy, OD_DATE) AS 'Year', OH_USER2 AS 'Store Type'
FROM STK_STOCK
INNER JOIN ORD_DETAIL ON STK_STOCK.STKCODE=ORD_DETAIL.OD_STOCK_CODE
INNER JOIN ORD_HEADER ON OD_ORDER_NUMBER=OH_ORDER_NUMBER
INNER JOIN SL_ACCOUNTS ON OH_ACCOUNT=CUCODE
WHERE STKCODE IN ('76958', '27225', '27221', '26962', '26959', '26961', '27226', '26963', '26960')
AND OD_QTYORD > 0
AND CUCODE != 'Z9997'
GROUP BY CUCODE, CUNAME, STKCODE, STKNAME, OD_GROSS, CUSORT, CUUSER1, OD_DATE, OH_USER2
) AS SourceTable
PIVOT
(
SUM([Packs Ordered])
FOR [Year] IN ([2016], [2017])
) AS PivotTable
) a
group by GROUPING SETS ( [Acct], [Customer], [Code], [Description], [Value], [Sale Person],
[Region], [Store Type] )
ORDER BY [Acct], [Customer], [Code], [Description], [Value], [Sale Person],
[Region], [Store Type];
Based on Kannan Kandasamy's reply I got this which worked beautifully:
SELECT (CASE
WHEN GROUPING([Acct])=0 AND
GROUPING([Customer]) = 1 AND
GROUPING([Code]) = 1 AND
GROUPING([Description]) = 1 AND
GROUPING([Sale Person]) = 1 AND
GROUPING([Region]) = 1 AND
GROUPING([Store Type]) = 1
THEN 'Total '+ [Acct]
WHEN GROUPING([Acct])=1 AND
GROUPING([Customer]) = 1 AND
GROUPING([Code]) = 1 AND
GROUPING([Description]) = 1 AND
GROUPING([Sale Person]) = 1 AND
GROUPING([Region]) = 1 AND
GROUPING([Store Type]) = 1
THEN 'Total'
ELSE [Acct]
END) AS Acct , ISNULL([Customer],'') AS 'Customer', ISNULL([Code],'') AS 'Code', ISNULL([Description],'') AS 'Description', SUM(ISNULL([Value],'')) AS 'Value', ISNULL([Sale Person],'') AS 'Sales Person',
ISNULL([Region],'') AS 'Region', ISNULL([Store Type],'') AS 'Store Type', SUM([2016]) AS '2016', SUM([2017]) AS '2017'
FROM
(
SELECT [Acct], [Customer], [Code], [Description], [Value], [Sale Person],
[Region], [Store Type], ISNULL([2016], 0) AS '2016', ISNULL([2017],0) AS
'2017'
FROM
(
SELECT CUCODE AS 'Acct', CUNAME AS 'Customer', STKCODE AS 'Code', STKNAME AS 'Description', SUM(OD_QTYORD) AS 'Packs Ordered'
, OD_GROSS AS 'Value', CUSORT AS 'Sale Person', LEFT(CUUSER1,3) AS 'Region', DATEPART(yyyy, OD_DATE) AS 'Year', OH_USER2 AS 'Store Type'
FROM STK_STOCK
INNER JOIN ORD_DETAIL ON STK_STOCK.STKCODE=ORD_DETAIL.OD_STOCK_CODE
INNER JOIN ORD_HEADER ON OD_ORDER_NUMBER=OH_ORDER_NUMBER
INNER JOIN SL_ACCOUNTS ON OH_ACCOUNT=CUCODE
WHERE STKCODE IN ('76958', '27225', '27221', '26962', '26959', '26961', '27226', '26963', '26960')
AND OD_QTYORD > 0
AND CUCODE != 'Z9997'
GROUP BY CUCODE, CUNAME, STKCODE, STKNAME, OD_GROSS, CUSORT, CUUSER1, OD_DATE, OH_USER2
) AS SourceTable
PIVOT
(
SUM([Packs Ordered])
FOR [Year] IN ([2016], [2017])
) AS PivotTable
) a
group by GROUPING SETS (( [Acct], [Customer], [Code], [Description], [Sale Person],
[Region], [Store Type]),([Acct]),());