SQL Design - Accounting for unknown values - sql

Say I have a table called HoursCharged
ChrgNum(varchar(10))
CategoryID(uniqueidentifier)
Month(datetime)
Hours(int)
CategoryID is a foreign key reference to another table in my database, which is just a name/ID pairing. ChrgNum is guaranteed to be unique outside of this database, and so I only check to see if it exists in my db already.
You should also know that this tool support several different groups from one database (hence the globally unique CategoryID, since different groups may potentially name the Categories the same thing, I needed to differentiate them).
This table is populated from a CSV file. The idea is that every combination of ChrgNum, CategoryID, and Month is going to be unique. The report that is being run to create the import file can only see a certain range (i.e. a year). Therefore the algorithm looks something like this:
IF (ChrgNum exists in database, CategoryID exists in database,
combo of ChrgNum/CategoryID/Month DOES NOT exist in table HoursBurned)
THEN add a new row for this entry
ELSE IF (ChrgNum exists in database, CategoryID exists in database,
combo of ChrgNum/CategoryID/Month DOES exist in table HoursBurned)
THEN update the existing row with the new Hours value.
This is all fine and good, except now my boss wants me to account for hours charged, in a particular month, for a known ChrgNum and an unknown Category.
My question is, how do I account for this? If I simply insert a NULL CategoryID, what happens if a totally seperate group charges hours to the same number and category? My other idea was to create a new table for the unknown Categories, but if I do this, and the first import has two unknown categories while the next one has one of the two again (which can happen) what do I do?
My head has been swirling around this for hours. Any help is appreciated!

Your boss presented you with this problem, so why not ask them? Because this really sounds like a business problem. If you have groups which are reporting on categories you don't know about then surely you should be attempting to synchronize your database with the systems which feed it?
Otherwise, what is wrong with having a single "Unknown" category? You are being asked to track the hours assigned to categories you don't currently track.

It seems to me like you should be adding the unrecognized categories to the existing categories table on the fly. If the problem is then distinguishing between categories with the same name from different groups, don't you already have that problem now?

Related

Adding record with new foreign key

I have few tables to store company information in my database, but I want to focus on two of them. One table, Company, contains CompanyID, which is autoincremented, and some other columns that are irrelevant for now. The problem is that companies use different versions of names (e.g. IBM vs. International Business Machines) and I want/need to store them all for futher use, so I can't keep names in Company table. Therefore I have another table, CompanyName that uses CompanyID as a foreign key (it's one-to-many relation).
Now, I need to import some new companies, and I have names only. Therefore I want to add them to CompanyName table, but create new records in Company table immediately, so I can put right CompanyID in CompanyName table.
Is it possible with one query? How to approach this problem properly? Do I need to go as far as writing VBA procedure to add records one by one?
I searched Stack and other websites, but I didn't find any solution for my problem, and I can't figure it out myself. I guess it could be done with form and subform, but ultimately I want to put all my queries in macro, so data import would be done automatically.
I'm not database expert, so maybe I just designed it badly, but I didn't figure out another way to cleanly store multiple names of the same entity.
The table structure you setup appears to be a good way to do this. But there's not a way to insert records into both tables at the same time. One option is to write two queries to insert records into Company and then CompanyName. After inserting records into Company you will need to create a query that joins from the source table to the Company table joining it on a field that uniquely defines the record beside the autoincrement key. That will allow you to get the key field from Company for use when you insert into CompanyName.
The other option, is to write some VBA code to loop through the source data inserting records into both. The would be preferable since it should be more reliable.

Counting value list items in FileMaker

Please see link to FileMaker Pro 12 database I've created to illustrate my problem:
https://dl.dropboxusercontent.com/u/24821795/Example.fmp12
I want to count the number of times an Activity has been assigned to a Staff member, but there are a couple of things making it tricky (not impossible, I hope):
When the user performs a Find, the count should update to only include the found records.
The user can add to the list of activities.
In the example provided, SelfJoinCount and Activities::Count are not what I want - they both count Activity (e.g. Archery has been assigned to two staff members), but do not meet criteria 1. above.
Try performing a Find of Gender = M
The values of ReviewedCount (a summary field, counting Reviewed) change to 3, which is what I want.
The values of SelfJoinCount and Activities::Count do not change. In this case, I want them to change to 1 (i.e. One record with Ballooning, one record with Bird watching and one record with Archery in the found set).
I could create a calculation field with a 1 in it if the activity occurs and then a summary field counting that 1 for every single activity in the database, BUT this won't work because of criteria 2. above (also, there are a lot of activities).
Any ideas?
Ok, several problems you have here.
First, you need key values for your tables. This can easily be accomplished by creating a number field in each table. In the options, select auto-enter serial number, validation unique, not empty.
Now, you need a 3rd table for the join. This table will have the foreign key value for the Staff member as well as the foreign key for the activity.
You will want to have your Staff layout in form view, add a portal into the join table with they foreign key field for the activity. Create a popup or drop down list for activities (hint: if you want the name of the activity to show in the layout rather than its key, use a popup.) it needs to have they key value and display second field, all values, show only value from second field.
This will allow you to have a many to many relationship between the tables so that a single staff member can have many activities and an activity can have many staff members.
Now, if you want a count of each activity, you could of course create calculation fields in the staff table to count instances of each activity type, but I find that cumbersome and time consuming as well as requiring you to create TO's for each activity. What you really want to use is an ExecuteSQL() function. Some thing like this:
ExecuteSQL("
SELECT COUNT(J.FK_ActivityID)
FROM JoinTable J
WHERE J.FK_StaffID =?
Group by J.FK_ActivityID";"";"";Staff::PK_StaffID)
You can tweak that ExecuteSQL to include a specific activity, or leave it as it is an include them all. Up to you how you do it.
If it wasn't 7am and having had no sleep, I would mock up the file for you, but I think you would do better testing it and working on it on your own.

Possible to have a table with variable columns?

It might be a stupid question, but here goes:
Is it possible to make a dynamic table that's able to contain rows with variable number of columns and custom column names?
I have glanced over EAV-modelling, but it seems heavy. A real life example could be this:
Let's say I have a register with customers. But each customer might have different information to be entered. And depending on what you want to enter, it should be reflected in the database. (I.E. every customer has different columns)
Is this impossible/probable?
Update:
The standard approach (i.e. having a table with all needed columns and saving information only into columns that make sense for a particular customer while setting the remaining ones to NULL) doesn't work for me because what I want can't use 'fixed' column names. Example one customer might want CVR-number and another might want their phonenumber as a reference number. And a third might want some completely different information. So to avoid having a table containing 500 columns, I have now thought of making an extra table containing rows of column-data. Like so: Id, Name, Value, CustomerId. So when I want information for a customer, all I have to do is to iterate through this table with a specific customer Id.
my own edit!:
Sorry for troubling you with this simple SQL-issue! :-) Have a nice day...
You could model this as a one-to-many relationship between a Customer and a CustomerAttributes table. Something like:
**Customer table**
CustomerId
LastName
FirstName
...
**CustomerAttributes table**
CustomerId
AttributeName
AttributeValue
This is not possible in Sql-Server. As Marco says, you can store each customer's data in xml.
If all the columns are known ahead of time and some customers use one set and other customers use a different set, then sub-tables with each set of columns is the normal approach.
If the columns are not known ahead of time, then how would the data even be used? No code or reports could refer to it. Perhaps it should be stored unstructured in a general purpose 'Notes' field.
As far as I know it's not possible in standard relational databases, but you can take a look at schema-less databases called 'No-SQL' like MongoDB

Creating Table Relationships

I am working on a VB.net (VS-2010, Win XP Pro 2 SP3), Employee Management Project. I need to keep track of Employee Leave Attendance and also each Equipment assigned to an Employee. How can I achieve this using SQLlite.
It will be very useful if you could provide me with examples as I am completely new to the field of SQL and VB.net
I think this can be done with two tables where one has the primary key while the other has a foreign key, but I am not sure. Also how many tables will I need for storing data in Leave and Equipment Form.
I went through other questions but I was unable to figure out a solution for my problem.
(Sorry, I cannot provide with images as this site prevents me from posting images without 10 reps)
Most problems are only as complex, and as simple as you make them. Out of habbit, nearly all tables end up with a unique ID field. There are exceptions, which I will call "link" tables, eg, ones that provide connection details between two data tables.
Now, in your senario
You would need a "holiday" table, where each row will contain the employee unique ID and either a start/finish date, eg, if they take half a day, it needs to be visible, or, just a year and value, eg in 2011, I booked, 2 lots of 35 hours, and 1 lot of 4 hours eg, Ive taken 2 weeks and half a day.
For the equipment, you would need a data table, since an item can only got to 1 employee, it depends if you're going to use this for booking or not, but if its just like a library, eg I currently have a loaner laptop, then you can just have an employee field in the equipment table. If you need a booking system, then you would require link tables and more complex.
Best way to work out your tables is to try and group your data, and then write the items on peices of paper and see how you as a human do it. After a while you end up able to do so in your head.

One mysql table with many fields or many (hundreds of) tables with fewer fields?

I am designing a system for a client, where he is able to create data forms for various products he sales him self.
The number of fields he will be using will not be more than 600-700 (worst case scenario). As it looks like he will probably be in the range of 400 - 500 (max).
I had 2 methods in mind for creating the database (using meta data):
a) Create a table for each product, which will hold only fields necessary for this product, which will result to hundreds of tables but with only the neccessary fields for each product
or
b) use one single table with all availabe form fields (any range from current 300 to max 700), resulting in one table that will have MANY fields, of which only about 10% will be used for each product entry (a product should usualy not use more than 50-80 fields)
Which solution is best? keeping in mind that table maintenance (creation, updates and changes) to the table(s) will be done using meta data, so I will not need to do changes to the table(s) manually.
Thank you!
/**** UPDATE *****/
Just an update, even after this long time (and allot of additional experience gathered) I needed to mention that not normalizing your database is a terrible idea. What is more, a not normalized database almost always (just always from my experience) indicates a flawed application design as well.
i would have 3 tables:
product
id
name
whatever else you need
field
id
field name
anything else you might need
product_field
id
product_id
field_id
field value
Your key deciding factor is whether normalization is required. Even though you are only adding data using an application, you'll still need to cater for anomalies, e.g. what happens if someone's phone number changes, and they insert multiple rows over the lifetime of the application? Which row contains the correct phone number?
As an example, you may find that you'll have repeating groups in your data, like one person with several phone numbers; rather than have three columns called "Phone1", "Phone2", "Phone3", you'd break that data into its own table.
There are other issues in normalisation, such as transitive or non-key dependencies. These concepts will hopefully lead you to a database table design without modification anomalies, as you should hope for!
Pulegiums solution is a good way to go.
You do not want to go with the one-table-for-each-product solution, because the structure of your database should not have to change when you insert or delete a product. Only the rows of one or many tables should be inserted or deleted, not the tables themselves.
While it's possible that it may be necessary, having that many fields for something as simple as a product list sounds to me like you probably have a flawed design.
You need to analyze your potential table structures to ensure that each field contains no more than one piece of information (e.g., "2 hammers, 500 nails" in a single field is bad) and that each piece of information has no more than one field where it belongs (e.g., having phone1, phone2, phone3 fields is bad). Either of these situations indicates that you should move that information out into a separate, related table with a foreign key connecting it back to the original table. As pulegium has demonstrated, this technique can quickly break things down to three tables with only about a dozen fields total.