View Full Version : Calculations with many-to-many relationship
elektr 04-20-2009, 05:49 AM Hi!
I tried to search for this but I am not sure how to search for this kind of problem as English is not my first language, sorry :)
I have this kind of situation:
I have a many-to-many relationship in my database and I have these three tables:
CUSTOMER_TABLE: Fields CUSTOMER_ID, CUSTOMER_BALANCE (currency)
ASSET_TABLE: Fields ASSET_ID, ASSET_VALUE (currency)
JOIN_TABLE: CUSTOMER_ID, ASSET_ID
Now, I need to calculate the following value for each customer: balances to assets ratio which = SumOfCUSTOMER_BALANCE/SumOfASSET_VALUE. I can do this easily if there is a one-to-many relationship (eg. customer is connected to 3 assets and each of these 3 assets is connected to the same customer). Then I just use the totals query in query builder and check if the relationship is one-to-many...
Now how could I approach this problem if for example I have a customer, who is connected to 2 assets and one of these 2 assets is in turn connected to some other customers? There can be situations where 4 assets are connected to 10 customers etc...
So far I have done this manually in Excel by making this a table with the following fields (just search-copy-paste):
CUSTOMER_ID_1, CUSTOMER_ID_2, ..., CUSTOMER_ID_N, ASSET_ID_1, ASSET_ID_2, ..., ASSET_ID_N, CUSTOMER_BALANCE_1, CUSTOMER_BALANCE_2, ..., CUSTOMER_BALANCE_N, ASSET_VALUE_1, ASSET_VALUE_2, ..., ASSET_VALUE_N
Then by summing all the customer balances and asset values, I calculate the correct balances to assets ratio. Now I know that it is stupid way to calculate it manually like this.... :D
I have only experience using the design view to build queries
Thanks in advance!
elektr
lagbolt 04-20-2009, 03:44 PM How does this work in the real world? Say five customers are linked to an asset worth $50. How do you determine that value of customer 2's asset?
elektr 04-20-2009, 09:50 PM Ok, an example:
Customer_1: Balance 10 $
Customer_2: Balance 10 $
Customer_3: Balance 10 $
Customer_4: Balance 10 $
Customer_5: Balance 10 $
Asset_1: Value 50 $
All customers are connected to Asset_1
Now balance to asset ratio = (10+10+10+10+10)/50= 50/50 = 1 (or let's say 100%)
Every customer has balance to asset ratio of 100%
2nd example with many-to-many:
Customer_1: Balance 10 $
Customer_2: Balance 10 $
Customer_3: Balance 10 $
Customer_4: Balance 10 $
Customer_5: Balance 10 $
Asset_1: Value 50 $
Asset_2: Value 50 $
Connections:
Customer_1 - Asset_1
Customer_1 - Asset_2
Customer_2 - Asset_2
Customer_3 - Asset_2
Customer_4 - Asset_2
Customer_5 - Asset_2
(Because of customer_1 there is a many-to-many relationship)
We have to use some sort of algorithm (so far I do this manually) to find all related customers and assets. Now we calculate the balance to assets ratio:
(10+10+10+10+10)/(50+50)=50/100=0.5 (50%) - this is the ratio for all customers
namliam 04-20-2009, 10:34 PM The trick is to make the assets 'unique' instead of grouped...
I.e. Make a query first to devide your assets by the number of customers to make the 'real' asset value (50 / 5 = 10)
Then make your totals query (like you would normaly make it) based upon above query.
Good luck !
lagbolt 04-20-2009, 11:30 PM Assuming tables...
tCustomer
CustomerID (PK, Long)
Customer (String)
Balance (Currency)
tAsset
AssetID (PK, Long)
AssetValue (Currency)
tCustomerAsset
CustomerAssetID (PK, Long)
CustomerID (Long)
AssetID (Long)
...and given that any asset that is linked to multiple customers is split evenly between them, you can return the Balance-To-Asset ratio using the following SQL.
SELECT Balance /
(SELECT Sum([tAsset].[AssetValue]/
(SELECT Count(*) AS CustomerCount
FROM tCustomerAsset AS t2
WHERE t2.AssetID = t1.AssetID)
) AS Asset
FROM tCustomerAsset AS t1 INNER JOIN tAsset ON t1.AssetID = tAsset.AssetID
WHERE t1.CustomerID = [prmCustomerID]
) AS Ratio
FROM tCustomer
WHERE CustomerID = [prmCustomerID]
I think. Note that the SQL will require you to supply prmCustomerID, which is the customer for whom you'd like to know the ratio.
khawar 04-20-2009, 11:30 PM What are the results you are expecting
elektr 04-20-2009, 11:50 PM I will try to explain more clearly:
All customers that are linked with an asset must have the same ratio, they can have different balances but the ratio will be calculated as sum of total balances divided by sum of total asset values. I cannot divide the asset value with the number of customers.
Now the tricky part is that when I have a relationship where one customer is connected to n assets and the n assets are in turn connected to other customers, then the calculation is not correct (according to the rule that I have to add up all customer balances and asset values)
I have done this so that I create a pivottable in access:
Column: count of customer (1, 2, 3, ... etc) - this value I get by counting how many customers are connected to each asset (sort by asset_ID and then number the customers, I do this in excel with if(asset_ID(previous record)=asset_ID(current record);previous record+1;1)
Row: Asset_ID
Value: Customer_ID
I attached an example in Excel with the pivot table, the expected result and the calculation.
khawar 04-20-2009, 11:57 PM Means you just want to have total balances / total ratio that doesnt seem complicated
khawar 04-20-2009, 11:59 PM On the basis on data you provided in post # 3 in this thread how the resultant query should look like
elektr 04-21-2009, 12:38 AM On the basis on data you provided in post # 3 in this thread how the resultant query should look like
That is exactly my challenge. I know how to do this by hand but not with code. In the pivot list, the assets have no duplicates. I first find if there are duplicate contracts in field 1, then when I find one, then I move the asset next to the first asset and delete the duplicate contract. Sometimes with the new asset, there come also new contracts. When I finish checking the first field, then I take the next until the last one. After that I will start checking if there are duplicate contracts in different fields etc etc....
khawar 04-21-2009, 12:45 AM Still not able to understand what are the results you want
elektr 04-21-2009, 12:49 AM I need to have all assets and clients which are connected on one field, without duplicate asset_ID and without duplicate customer_ID
Thanks for the help so far :)
khawar 04-21-2009, 01:08 AM Download attached file and check queryFinal should it be like this
elektr 04-21-2009, 01:59 AM this is very good already but....
I need to have each group of assets-customers as a different record in the database. So there will be n number of fields for assets (n=maximum number of assets which are connected with each other by customers) and n number for customers (same rule).
I added some data to the example Excel file and the expected result
And thanks again for trying to help :)
khawar 04-21-2009, 02:05 AM i CANT UNDERSTAND THE CALCULATION BECAUSE I HAVE NOT SEEN THE ORIGINAL DATA
Tell me the customer balances and asset values
elektr 04-21-2009, 02:25 AM I attached the db (I updated the tables with the information from the Excel file) and Excel file, this is how it should work
khawar 04-21-2009, 02:34 AM Customer 5 also belongs to asset3 and asset4 why asset4 is not in category 1 i mean first record
elektr 04-21-2009, 02:43 AM yeah, sorry, had it wrong, uploaded again.
khawar 04-21-2009, 11:38 PM Download the attached file and check if it fulfills your requirement
elektr 04-22-2009, 01:16 AM khawar, you are a genius, this is exactly what I need!
by the way, can you please modify the query so that there is no "AssetValue" field in table Assets and no "Balance" field in table Customers? The result would be just the combinations of customers and assets without the numeric calculation.
wow, thanks again for this elegant solution :)
khawar 04-22-2009, 01:19 AM I think you can do it yourself now
elektr 04-22-2009, 01:23 AM Ok, never mind, I'll figure it out. Cheers
lagbolt 04-22-2009, 09:20 AM I posted the solution already.
Here it is implemented.
elektr 04-22-2009, 10:10 PM Do you know if there are any articles that describe this kind of problem and the solution?
khawar 04-22-2009, 10:12 PM Is your problem still not solved
elektr 04-22-2009, 11:08 PM it's solved, I just want to educate myself.
By the way, I ran the query with about 3000 assets and 3000 customers and it worked perfectly giving the result in about 5 minutes. Now I am testing it with 30000 assets and about 25000 customers (all have many-to-many relationships). Access gave me "File sharing lock count exceeded" error message, so I increased maxlocksperfile to 1000000 (see http://support.microsoft.com/kb/815281). Now it is running again, I'll let you know when it finishes.
elektr 04-23-2009, 12:01 AM It is still giving me "file sharing lock count exceeded. increase maxlocksperfile registry entry" I cannot change my registry because of policy restrictions. I typed "DAO.DBEngine.SetOption dbmaxlocksperfile,1000000" into immediate window and pressed return. After running the code again, still same error.
khawar 04-23-2009, 12:05 AM At which routine it gives the error I think its Update Sequences
elektr 04-23-2009, 12:10 AM How can I check this? The code runs for about 2 hours until it gives this error.
khawar 04-23-2009, 12:12 AM can you upload database zipped (if possible)
elektr 04-23-2009, 01:06 AM can you upload database zipped (if possible)
I can upload data if you state that you will not charge any money now or in the future for this help. Sorry for that, corporate regulations.
elektr 04-23-2009, 01:47 AM By the way, the file is 1074 KB, where can I upload it for you?
khawar 04-23-2009, 01:49 AM We are here to solve your problems and giving you advice no one can charge you for giving advice on this forum
khawar 04-23-2009, 01:50 AM you can upload it here
elektr 04-23-2009, 01:55 AM it is too large for uploading here, maybe I can use some uploading site? Which one do you prefer?
khawar 04-23-2009, 02:01 AM what is the size of file
elektr 04-23-2009, 02:04 AM 1074 KB, the limit on this forum for .zip is 785.9 KB
khawar 04-23-2009, 02:09 AM you can check your self where the code breaks by stepping into the code
and by the way how many assets and customers you have in database
elektr 04-23-2009, 02:14 AM it does not break when I run through the cycle. The code runs for about 2 hours and then gives me this error. I have 16 000 assets and 16 500 customers and there are 30 000 relationships between them. The algorithm is correct but I guess there is some Access memory handling problem involved.
khawar 04-23-2009, 02:17 AM I cant guess I have to see whats happenings
elektr 04-23-2009, 02:32 AM ............
|
|