Using Data from One Table in Another Table in Access - database

Hallo StackOverflow Users
I am struggling with transferring values between Access database tables which I will use in a Delphi program to tally election votes and determine the winning candidates. I have a total of six tables. One is my overall table, tblCandidates which identifies each candidate and contains the amount of votes they received from each party, namely the Grade Heads, the Teachers and the Learners. When it comes to the Learners we have four participating grades, namely the grade 8’s, 9’s, 10’s and 11’s, and each grade again has multiple participating classes, namely class A, B, C, etc.
Now, I have set up tables for each grade that contains all the classes in that grade. I named these tables tblGrX with X being the grade represented by 8 through 11. Each one of these tables has two extra fields, namely a field to identify a candidate and a field that will add up all the votes that candidate received from each of the classes in that grade. Lastly I have another table, tblGrTotals with fields Total_GrX (once again with X being the grade), that will contain all the total votes a candidate received from each grade, adding them up in another field for my tblCandidates table to use in its Total_Learners field.
So in short, I want, for example, tblGrTotals to use the value in the field Total of tblGr8 in its Total_Gr8 field, and then tblCandidates to use the value in field Total of tblGrTotals in its Total_Learners field. Is there any way to keep these values updated between tables like cells are updated in Excel the moment a change is made?
Thank you in advance!

You need to rethink your table design. I guess your background is Excel, and your tables are laid out like you would do in Excel sheets, but a relational database works differently.
Think about the objects you are modelling.
Candidates - that's easy. ID, Name, perhaps additional info that belongs to each candidate. But nothing about votes here.
"Groups that are voting" or Parties. Not so trivial, due to the different types of parties. Still I would put them in one table, with Grade and Class only set for Learners, NULL for Heads and Teachers.
e.g.
+----------+------------+-------+-------+
| Party_ID | Party_Type | Grade | Class |
+----------+------------+-------+-------+
| 1 | Head | | |
| 2 | Teacher | | |
| 3 | Learner | 8 | A |
| 4 | Learner | 8 | B |
| 5 | Learner | 8 | C |
| 6 | Learner | 9 | A |
| 7 | Learner | 9 | B |
| 8 | Learner | 10 | A |
+----------+------------+-------+-------+
Votes: they are a Junction Table between Candidates and Parties.
e.g.
+----------+--------------+-----------+
| Party_ID | Candidate_ID | Num_Votes |
+----------+--------------+-----------+
| 1 | 1 | 5 |
| 1 | 2 | 17 |
| 3 | 1 | 2 |
| 3 | 2 | 6 |
| 3 | 3 | 10 |
+----------+--------------+-----------+
Now: if you want to know the votes of Class 8A:
SELECT Candidate_ID, SUM(Num_Votes)
FROM Parties p INNER JOIN Votes v
ON p.Party_ID = v.Party_ID
WHERE p.Party_Type = 'Learner'
AND p.Grade = 8
AND p.Class = 'A'
GROUP BY Candidate_ID
Or of all Grade 8? Simply omit the p.Class criteria.
For the votes per candidate you join Candidates with Votes.
Edit:
for the votes counting differently, this is an attribute of Party_Type.
We don't have a table for them yet, so create one:
+------------+---------------+
| Party_Type | Multiplicator |
+------------+---------------+
| Head | 4 |
| Teacher | 3 |
| Learner | 1 |
+------------+---------------+
and to count all votes:
SELECT c.Candidate_ID, c.Candidate_Name, SUM(v.Num_Votes * t.Multiplicator) AS SumVotes
FROM Parties p
INNER JOIN Votes v ON p.Party_ID = v.Party_ID
INNER JOIN Party_Types t ON p.Party_Type = t.Party_Type
INNER JOIN Candidates c ON v.Candidate_ID = c.Candidate_ID
GROUP BY c.Candidate_ID, c.Candidate_Name
With a design like this, you don't need to keep updating data from one table into another - you calculate it when and how you need it, and it's always current.
The magic of databases. :)

Related

is this a good practice for a database for products with multiple units,cost price & expiry dates

I a working on a database that is going to have a product with multiple expiration date, multiple cost prices and therefore there will multiple stock entries for the same product, I have made an initial database design for this and I wanted to ask you guys if this is a good practice or not. If not please advise me on how to do it the right way.
This is what I have thought about so far.
Creating 3 tables (1. Product_info - 2.Product_Stock - 3.units)
and below is the detailed structure:
Units Table
--------------------------
id Name
|------|
1 |Piece |
2 |Pack |
3 |Kilos |
Here I will list all the units that I will use as the base product unit.
Product Information Table
-----------------------------------------------------------------------------------------------------------------------
id Name AvgCostPrice AvgPrice AvgPackCostPrice AvgPackPrice totalQuantity BaseUnitID multiplier PackBarcode Barcode
|------|------------|--------|----------------|------------|-------------|----------|----------|------------|--------|
1 |Soda | | | | | 108 | 1 | 12 | 111111 | 111222 |
2 |Water | | | | | 50 | 1 | 6 | 222222 | 222111 |
in the above table the average cost price and selling price for the packs and piece will be calculated from the different stocks I have for the said product.
The multiplier column will be for how much pieces does a product pack hold.
The Total Quantity will hold the sum of different stock quantities I have in the (Product Stock Table) ,Also it will only sum the quantity for base unit of the product.
for example: if the base unit of soda is pack, then it will sum the (PackQTY) Column in (Product Stock Table). and if else it will sum (Quantity) in that table.
Product Stock Table
---------------------------------------------------------------------------------------------------------------------------
id ProdID UnitID CustomBarcode Quantity PackQTY CostPrice Price PackCostPrice PackPrice expDate Enabled
|------|-------|--------------|-------------|-------|----------|-------|--------------|---------|--------------|---------
1 |1 | 1 | | 84 | 7 | 2.0 | 2.4 | 24.0 | 29 | 20/may/2019 | 1
2 |1 | 1 | | 24 | 2 | 1.5 | 1.9 | 18.0 | 23 | 10/aug/2019 | 1
2 |2 | 3 | | 50 | 0 | 3.0 | 5.0 | 0.0 | 0 | 10/Feb/2019 | 1
1.The enabled column will work as a (Boolean) to determine whether to use this stock while selling.
for example: if I wanted to sell a soda Can and I have two Stocks for it. if stock number one is 0 then enable column will be false and therefore it will only subtract the quantity sold from stock number two and use its price and cost price in the (SalesDetails Table)
Custom Barcode Column will be used to separate stocks when having a discount on almost expired stock.
And I also thought of separating the different units for each product stock in (Stock Table)
So, when I want to sell 24 pieces of soda and 3 packs of soda it will choose the oldest stock depending on its (Enabled Column Value = True)and subtract that quantity from it and if it reaches zero then (Enabled column) Value will change to false.
after that it will go again and do the same but this time it will change the value of PackQtY from 7 to 4 and the Quantity Column Value will be calculated through this [ Product_Stock.Quantity= Product_Stock.Quantity - (QtySold * Prodcut_info.Multiplier Column Value) ] which will be 84-(3*12)= 48
And the sales details structure output will be like this:
Sale Details Table
----------------------------------------------------------
id ProdID UnitID Quantity CostPrice Price total CostTotal
|------|-------|-----------|-------------|-------|------|---------|
1 |1 | 1 | 24 | 2.0 | 2.4 | 57.6 | 48.0 |
2 |1 | 2 | 3 | 18.0 | 23.0 | 69.0 | 54.0 |
Product Stock Table (After Selling 24 pieces of Soda and 3 packs of Soda)
---------------------------------------------------------------------------------------------------------------------------
id ProdID UnitID CustomBarcode Quantity PackQTY CostPrice Price PackCostPrice PackPrice expDate Enabled
|------|-------|--------------|-------------|-------|----------|-------|--------------|---------|--------------|---------
1 |1 | 1 | | 48 | 4 | 2.0 | 2.4 | 24.0 | 29 | 20/may/2019 | 1
2 |1 | 1 | | 0 | 0 | 1.5 | 1.9 | 18.0 | 23 | 10/aug/2019 | 0
Sorry if I didn't explain it very well.
Thank you very much in advance.
Firstly, you need to be careful about how you use nouns.
For example: "Price" does not mean the same as "Cost" and "CostPrice" sounds like an oxymoron. I suggest that you restrict your yourself to using either Cost or Price.
Van Ng asks if you have done an Entity Relationship diagram. Well, at the stage that you seem to be at, it is probably unwise to start with an ER diagram because an ER diagram is helpful as a summary of a model that you have already defined - and you are not yet at that stage.
Averages: If you design your database schema correctly then you can calculate data such as averages. You don't need averages as base tables.
I recommend that you consider using the fact-based modeling method called "object-role modeling"(ORM) because you can start with "the facts" before thinking about drawing ER diagrams.
Example:
I used the NORMA ORM tool to create the following example:
First, I read your text, extracted facts and then used the facts to design an object-role model.
Then I used the NORMA tool to generate a "logical view" of the object-role model. (happens in milliseconds)
I did not add everything that you mention but I hope that this will be enough to help you to make progress.
The example contains two artefacts:
1: The logical model that was generated by the NORMA tool.
2: The facts from which the logical model was generated.
[

Traversing and Getting Nodes in Graph without Loop

I have a person table which keeps some personal info. like as table below.
+----+------+----------+----------+--------+
| ID | name | motherID | fatherID | sex |
+----+------+----------+----------+--------+
| 1 | A | NULL | NULL | male |
| 2 | B | NULL | NULL | female |
| 3 | C | 1 | 2 | male |
| 4 | X | NULL | NULL | male |
| 5 | Y | NULL | NULL | female |
| 6 | Z | 5 | 4 | female |
| 7 | T | NULL | NULL | female |
+----+------+----------+----------+--------+
Also I keep marriage relationships between people. Like:
+-----------+--------+
| HusbandID | WifeID |
+-----------+--------+
| 1 | 2 |
| 4 | 5 |
| 1 | 5 |
| 3 | 6 |
+-----------+--------+
With these information we can imagine the relationship graph. Like below;
Question is: How can I get all connected people by giving any of them's ID.
For example;
When I give ID=1, it should return to me 1,2,3,4,5,6.(order is not important)
Likewise When I give ID=6, it should return to me 1,2,3,4,5,6.(order is not important)
Likewise When I give ID=7, it should return to me 7.
Please attention : Person nodes' relationships (edges) may have loop anywhere of graph. Example above shows small part of my data. I mean; person and marriage table may consist thousands of rows and we do not know where loops may occur.
Smilar questions asked in :
PostgreSQL SQL query for traversing an entire undirected graph and returning all edges found
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=118319
But I can't code the working SQL. Thanks in advance. I am using SQL Server.
From SQL Server 2017 and Azure SQL DB you can use the new graph database capabilities and the new MATCH clause to answer queries like this, eg
SELECT FORMATMESSAGE ( 'Person %s (%i) has mother %s (%i) and father %s (%i).', person.userName, person.personId, mother.userName, mother.personId, father.userName, father.personId ) msg
FROM dbo.persons person, dbo.relationship hasMother, dbo.persons mother, dbo.relationship hasFather, dbo.persons father
WHERE hasMother.relationshipType = 'mother'
AND hasFather.relationshipType = 'father'
AND MATCH ( father-(hasFather)->person<-(hasMother)-mother );
My results:
Full script available here.
For your specific questions, the current release does not include transitive closure (the ability to loop through the graph n number of times) or polymorphism (find any node in the graph) and answering these queries may involve loops, recursive CTEs or temp tables. I have attempted this in my sample script and it works for your sample data but it's just an example - I'm not 100% it will work with other sample data.

Django QuerySet - Multiple Order By when there is a single field per record

I am accessing an API where the number of fields can change at any time, but I must store and display the data as a table. Therefore, each record from the API is stored as a single record per field. My problem is that I am having trouble working out how I would order by multiple columns at a time. Putting all of the data into a 2D array (list of lists) before sorting is not a viable option as the number of records could be too large to feasibly hold in memory.
I've put together a simple example to explain. If anyone has an idea on how to overcome the problem, or how I could redesign my approach, I'd be very grateful.
| record_id | field | data |
| 1 | x | 2 |
| 1 | y | 1 |
| 1 | z | 3 |
| 2 | x | 30 |
| 2 | y | 42 |
| 2 | z | 7 |
| 3 | x | 53 |
| 3 | y | 2 |
| 3 | z | 7 |
If ordering by fields 'z' then 'x' (both ascending), the record order would be 1,2,3
If ordering by fields 'z' then 'y' (both ascending), the record order would be 1,3,2
I am using models in django to store and I am using QuerySets to retrieve the data. I don't have any control over the API or database from which I am originally accessing the data.
After a fair amount of research I realised I was going about this all wrong - I am now using an hstore field in postgres and django-hstore to utilise it, for a schema-less approach. I now have a single row per original record and I can order_by after casting the required field in an 'extra' method.

Ingredients for drink new table or string in column?

I am thinking about my application and I want to store data about drinks. Now I am thinking what is best that if I save ingredients just as nvarchar column in table with drink or if I create new table with ingredients and create relationship one to many? I want database to be just read-only and I want to have option filter by ingredients. So what´s best way for windows phone (for performance)? And if the new table would be the better choice, I should use EntitySet, EntityRef, am I right? And I would have for every ingredient new row in table? Let´s say I have 100drinks, in average that every drink has 4ingredients so I have in first table 100rows and in second cca 400rows? Thanks for help
Actually, both solutions proposed are wrong. A drink can have many ingredients and an ingredient can be used in many drinks. Hence, we have a many-to-many relationship here. The proper way to model this is the following (I'm adding data for it to be more understandable):
Ingredients (PK: Id)
+----+--------------------+
| Id | Name |
+----+--------------------+
| 1 | Water |
| 2 | Sugar |
| 3 | Coffe |
| 4 | Virgin Islands Tea |
| 5 | Ice |
+----+--------------------+
Drinks (PK: Id)
+----+-------------+
| Id | Name |
+----+-------------+
| 1 | Black Coffe |
| 2 | Tea |
| 3 | Ice Tea |
+----+-------------+
Drinks_Ingredients (PK: Drink_Id, Ingredient_Id)
+----------+---------------+------------+
| Drink_Id | Ingredient_Id | Proportion |
+----------+---------------+------------+
| 1 | 1 | 70 |
| 1 | 2 | 10 |
| 1 | 3 | 20 |
| 2 | 1 | 90 |
| 2 | 4 | 10 |
| 3 | 1 | 80 |
| 3 | 4 | 10 |
| 3 | 5 | 10 |
+----------+---------------+------------+
I'm adding this Proportion column to show you how to add data that is dependant on the pair of drink-ingredient. Now, if you're worried about the size of the tables it'll be quite small as the only tables that will have the more complex data types (varchars) will be the ingredients and drinks tables, which will have the minimum amount of records possible: one per each drink and one per each ingredient.
If you still have doubts keep looking at the example, you'll get it :)
I would do a table for ingredients with a description and an id, and store the ids in the drink table cause it's the elegant way to do it. For 100 drinks, you won't see a difference for the performance.

Fill sequence in sql rows

I have a table that stores a group of attributes and keeps them ordered in a sequence. The chance exists that one of the attributes (rows) could be deleted from the table, and the sequence of positions should be compacted.
For instance, if I originally have these set of values:
+----+--------+-----+
| id | name | pos |
+----+--------+-----+
| 1 | one | 1 |
| 2 | two | 2 |
| 3 | three | 3 |
| 4 | four | 4 |
+----+--------+-----+
And the second row was deleted, the position of all subsequent rows should be updated to close the gaps. The result should be this:
+----+--------+-----+
| id | name | pos |
+----+--------+-----+
| 1 | one | 1 |
| 3 | three | 2 |
| 4 | four | 3 |
+----+--------+-----+
Is there a way to do this update in a single query? How could I do this?
PS: I'd appreciate examples for both SQLServer and Oracle, since the system is supposed to support both engines. Thanks!
UPDATE: The reason for this is that users are allowed to modify the positions at will, as well as adding or deleting new rows. Positions are shown to the user, and for that reason, these should show a consistence sequence at all times (and this sequence must be stored, and not generated on demand).
Not sure it works, But with Oracle I would try the following:
update my_table set pos = rownum;
this would work but may be suboptimal for large datasets:
SQL> UPDATE my_table t
2 SET pos = (SELECT COUNT(*) FROM my_table WHERE id <= t.id);
3 rows updated
SQL> select * from my_table;
ID NAME POS
---------- ---------- ----------
1 one 1
3 three 2
4 four 3
Do you really need the sequence values to be contiguous, or do you just need to be able to display the contiguous values? The easiest way to do this is to let the actual sequence become sparse and calculate the rank based on the order:
select id,
name,
dense_rank() over (order by pos) as pos,
pos as sparse_pos
from my_table
(note: this is an Oracle-specific query)
If you make the position sparse in the first place, this would even make re-ordering easier, since you could make each new position halfway between the two existing ones. For instance, if you had a table like this:
+----+--------+-----+
| id | name | pos |
+----+--------+-----+
| 1 | one | 100 |
| 2 | two | 200 |
| 3 | three | 300 |
| 4 | four | 400 |
+----+--------+-----+
When it becomes time to move ID 4 into position 2, you'd just change the position to 150.
Further explanation:
Using the above example, the user initially sees the following (because you're masking the position):
+----+--------+-----+
| id | name | pos |
+----+--------+-----+
| 1 | one | 1 |
| 2 | two | 2 |
| 3 | three | 3 |
| 4 | four | 4 |
+----+--------+-----+
When the user, through your interface, indicates that the record in position 4 needs to be moved to position 2, you update the position of ID 4 to 150, then re-run your query. The user sees this:
+----+--------+-----+
| id | name | pos |
+----+--------+-----+
| 1 | one | 1 |
| 4 | four | 2 |
| 2 | two | 3 |
| 3 | three | 4 |
+----+--------+-----+
The only reason this wouldn't work is if the user is editing the data directly in the database. Though, even in that case, I'd be inclined to use this kind of solution, via views and instead-of triggers.

Resources