简体   繁体   中英

Showing a record count as a percentage of totals of groups of records in a crosstab query, Access SQL

I'm building an offline DB in access and when grouping data, I group on Company ID, then Date, then Prelim Size. Then there's a further classification to show breakages for each record. There are 5 categories in breakages, which are then transformed into column headings using a pivot table.

I need to calculate the percentage that the record count of a sub-group is of that group.

I have the pivot table producing the results, but what I am missing is to show that number as a percentage of the total of that row. So on the first record, I want to add up 5 + 2 + 2 + 3 + 3 which is 15, and show each of those values as a percent of 15.

Current table result:

enter image description here

Bag_Company_ID, Shift_Date, Prelim_Size, 1 - Unbroken, 2 - Chipped, 3 - Lightly Broken, 4 - Heavily Broken, 5 - Fragment

10 2016/05/20 10 Ct 5 2 2 3 3

10 2016/05/20 3 - 4 Ct 4 5 1 3 5

10 2016/05/20 3 - 6 Gr 1 2 1 3 0

TRANSFORM Count(list_Breakages.Class_Cat) AS Cat
SELECT tbl_Bags.Bag_Company_ID, Format([Audit_PreVal_Date],"Short Date") AS Shift_Date, Client_Parcels.Prelim_Size
FROM list_Breakages INNER JOIN (tbl_Bags INNER JOIN Client_Parcels ON tbl_Bags.Bag_ID = Client_Parcels.Bag_ID) ON list_Breakages.Breakages_ID = Client_Parcels.Breakages
WHERE (((Client_Parcels.Prelim_Size) Is Not Null))
GROUP BY tbl_Bags.Bag_Company_ID, Format([Audit_PreVal_Date],"Short Date"), Client_Parcels.Prelim_Size
PIVOT list_Breakages.Class_Cat;

You will need an additional query using the crosstab as the source. Crosstab being a special query does not allow expressions in the pivoted values except whole aggregates. However, before doing so, add the Count(list_Breakages.Class_Cat) as a new field which will serve as the denominator in second query:

Crosstab Query

TRANSFORM Count(list_Breakages.Class_Cat) AS Cat
SELECT tbl_Bags.Bag_Company_ID, Format([Audit_PreVal_Date],"Short Date") AS Shift_Date, 
       Client_Parcels.Prelim_Size, Count(list_Breakages.Class_Cat) As TotalCatCount
FROM list_Breakages 
INNER JOIN (tbl_Bags 
INNER JOIN Client_Parcels ON tbl_Bags.Bag_ID = Client_Parcels.Bag_ID) 
    ON list_Breakages.Breakages_ID = Client_Parcels.Breakages
WHERE (((Client_Parcels.Prelim_Size) Is Not Null))
GROUP BY tbl_Bags.Bag_Company_ID, Format([Audit_PreVal_Date],"Short Date"), 
         Client_Parcels.Prelim_Size
PIVOT list_Breakages.Class_Cat;

Pct Query

SELECT c.Bag_Company_ID, c.Shift_Date, c.Prelim_Size,
       (c.[1 - Unbroken] / c.TotalCatCount) As c.[1-Unbroken_Pct], 
       (c.[2 - Chipped] / c.TotalCatCount) As c.[2-Chipped_Pct], 
       (c.[3 - Lightly Broken] / c.TotalCatCount) As c.[3-Lightly-Broken_Pct],  
       (c.[4 - Heavily Broken] / c.TotalCatCount) As c.[4-Heavily-Broken_Pct], 
       (c.[5 - Fragment] / c.TotalCatCount) As c.[5-Fragment_Pct]
FROM CrossTabQuery c

Alternatively, consider a conditional aggregate query, especially since your pivoted columns are a handful of 5. This is usually the pivot query form used in most RDMS (as the crosstab is unique to MS Access SQL). Here, layered expressions are allowed. Should your column values run 20+, consider above second query approach:

SELECT tbl_Bags.Bag_Company_ID, Format([Audit_PreVal_Date],"Short Date") AS Shift_Date, 
       Client_Parcels.Prelim_Size,
       SUM(IIF(list_Breakages.Class_Cat = '1 - Unbroken', 1, 0)) / 
           Count(list_Breakages.Class_Cat) AS [1 - Unbroken],
       SUM(IIF(list_Breakages.Class_Cat = '2 - Chipped', 1, 0)) / 
           Count(list_Breakages.Class_Cat) AS [2 - Chipped],
       SUM(IIF(list_Breakages.Class_Cat = '3 - Lightly Broken', 1, 0)) / 
           Count(list_Breakages.Class_Cat) AS [3 - Lightly Broken],
       SUM(IIF(list_Breakages.Class_Cat = '4 - Heavily Broken', 1, 0)) / 
           Count(list_Breakages.Class_Cat) AS [4 - Heavily Broken],
       SUM(IIF(list_Breakages.Class_Cat = '5 - Fragment', 1, 0)) / 
           Count(list_Breakages.Class_Cat) AS [5 - Fragment] 
FROM list_Breakages 
INNER JOIN (tbl_Bags 
INNER JOIN Client_Parcels ON tbl_Bags.Bag_ID = Client_Parcels.Bag_ID) 
ON list_Breakages.Breakages_ID = Client_Parcels.Breakages
WHERE (((Client_Parcels.Prelim_Size) Is Not Null))
GROUP BY tbl_Bags.Bag_Company_ID, Format([Audit_PreVal_Date],"Short Date"), 
         Client_Parcels.Prelim_Size;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM