HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Fill percentage of total field conditional on some other field with MS Access SQL

Submitted by: @import:stackexchange-dba··
0
Viewed 0 times
totalfillfieldwithsqlconditionalsomeaccessotherpercentage

Problem

This question is an extension of Fill percentage of total field with MS Access SQL.

I have the following 2013 MS Access SQL query:

UPDATE MyTable
SET F = f / DSUM("f", "MyTable") ;


This query fills field F with the percentage over the total of some field f, such that each one of the records F(i) in field F is given by:

F(i) = f(i)/SUM_i(f(i))


Both fields f and F belong to table MyTable.

Now, I would like, instead of simply computing the percentage over the whole table, to do it by Date, where Date is a 3rd field also to be found in table MyTable. I will make up an example for illustration purposes. Let's assume a simplified MyTable with 2 records per date; then that's what I would like MyTable to look like after executing my desired query... - see fields f and F:

|    Date    | Department |     f     |     F     |
|------------|------------|-----------|-----------|
|     t1     |     D1     |     2     |    40%    |
|     t1     |     D2     |     3     |    60%    |
|     t2     |     D1     |     1     |    20%    |
|     t2     |     D2     |     4     |    80%    |


... And this is how it is looking right now, after executing the query displayed above:

|    Date    | Department |     f     |     F     |
|------------|------------|-----------|-----------|
|     t1     |     D1     |     2     |    20%    |
|     t1     |     D2     |     3     |    30%    |
|     t2     |     D1     |     1     |    10%    |
|     t2     |     D2     |     4     |    40%    |


I have tried the following code, but none yielded what I wanted.

Try #1:

UPDATE MyTable
SET F = f / DSUM("f", "MyTable", "Date");


Try #2:

UPDATE MyTable
SET F = f / DSUM("f", "MyTable", "Date=Date");


Any ideas on how I could manage to do this?

Note: I have just called the two fields "f" and "F" here for illustration purposes, it is not how they are named in the actual DB.

I will add here further tests that haven'

Solution

Your last UPDATE statement should work. Access is often a bit crap though so although it should work, it probably won't. Thanks Microsoft Access dev team (probably more specifically the updates to JET).

Unfortunately, the only way I can recommend is to create a temp table based on a query which does a GROUP BY on the Date column you are attempting to aggregate. So create a query first like this:

SELECT MyTable.Date, Sum(MyTable.f) AS SumOfVal INTO temp_DateSums
FROM MyTable
GROUP BY MyTable.Date;


Then create another query which joins to this new table and performs its update based on it. This second query would look like:

UPDATE MyTable 
INNER JOIN temp_DateSums ON MyTable.Date = temp_DateSums.DateDate 
SET MyTable.F = [MyTable].[f]/[temp_DateSums].[SumOfVal];


This should update the column you need with the right value, albeit running 2 queries instead of one. I can't think of another way around it running a single query where you wouldn't get the dreaded "Operation must use an updatable query" option, that doesn't use VBA. Again, your DSUM should work, but DSUM doesn't seem to want to work the way it was designed anymore...

Code Snippets

SELECT MyTable.Date, Sum(MyTable.f) AS SumOfVal INTO temp_DateSums
FROM MyTable
GROUP BY MyTable.Date;
UPDATE MyTable 
INNER JOIN temp_DateSums ON MyTable.Date = temp_DateSums.DateDate 
SET MyTable.F = [MyTable].[f]/[temp_DateSums].[SumOfVal];

Context

StackExchange Database Administrators Q#156797, answer score: 4

Revisions (0)

No revisions yet.