It's not, that we don't have the time, but a forum is not interactively enough. It would be best, if you could really meet someone having a database design experience and work together on a table design.
You're too focused on the layout aspect. The database isn't there to store data in it's representational form. That's also a reason, why Excel sheets are not database table, they just have the aspect of a tabular layout. Any cell can have any value, but even if your service column rows all have the same type, it's still a wrong design. I already told you the table design: clientid, serviceid, month. Instead of 30 service columns it will have 30 records for each client, so two clients will lead to 60 record etc. It's simply new records, its data, not structure.
And to display the data you store in that way you'll either fill in an excel sheet or a grid in the way you want, that's then doing denormalisation. But for storage you go the inverse way and put each cell value in one record combined with clientid, serviceid and month number. Cells with NULL are not stored in a record and when you later create the grid no record for a combination of month, client and service simply means a NULL in that cell. So it's kind of storing coordinates and values per record.
Additional to that table, of course you will need two further tables with lists of clients and services, each of them would have an ID column and a name, either clientname or servicename. The IDs in these tables is called primary keys, they must be unique per table, eg you create a numeric sequence and have IDs 1,2,3,4... for clients and services. and the clientid and serviceid fields of the table storing the amounts, are references to these IDs, they move there from the client and services tabes, so they are foreign there, that's why they are called foreign keys.
A short sample with less rows and columns would look like this:
Code:
month service1 service2
client1 1 0.1 0.5
client1 2 0.2 0.6
client2 1 0.3 NULL
client2 2 0.4 0.8
clients:
id name
1 client1
2 client2
services:
id name
1 service1
2 service2
clientservices
clientid, serviceid, month, amount
1 1 1 0.1
1 1 2 0.2
1 2 1 0.5
1 2 2 0.6
2 1 1 0.3
2 1 2 0.4
2 2 2 0.8
This structure of data storage does never need to change, no matter how many clients there are, no matter how many services there are, no matter how many months you would observe. The NULL in one of the cells is not in the data, because there is no record for clientid 2, service id 2 and month 1. Or the other way around: No record is needed to denote a missing value, it's not there.
This data structure allows to easily do statistics on eg the average amount of all services all clients did or used by SELECT AVG(amount) FROM clientservices. If you had seperate fields to store amounts of service1 and service2, you'd need to compute SUM(service1amount+service2amount) and divide by 2*COUNT(*). And that's just one example on how this is easier to maintain. Additional to this structure you make up table and field rules, eg you don't allow a double record with same clientid, serviceid and month, each combination only is allowed once. It's easy to do with a candidate index.
Bye, Olaf.