I have a table full of items, at the moment there is only one type and everything about that item is in the same table. Now I want to add two more types. A number of columns (>10) will be unique to each type, so I don't just want to have 30 columns in the table when 20 of them will be null values, so I'm thinking of splitting them up:
tbl_items_common
tbl_items_type1 [for data unique to this type]
tbl_items_type2 [for data unique to this type]
tbl_items_type3 [for data unique to this type]
All the tables will have a common field 'id', for matching up the items and data.
Now I'm thinking about the coding and thinking:
Should I bother splitting these up at all, or should I just have one big table. Makes inserting and querying easier, but the db is a bit more 'messy'.
Splitting the data up makes the db a bit more isolated, but makes code more complicated.
Or, I could just use 3 completely separate tables with the some of the columns the same between them, but then I'm not sure how to generate a unique id that is unique over all 3 tables.
If I do decide on splitting the data up, is it possible to get all the data in one query (embedded case/select maybe?), or would I have to do a SELECT first to find the item type and then another to grab the rest of the data? Not pretty when it comes to reporting.
So what do I want to know? (1) Which method would you choose and (2) If you choose the second, how would you query that data?
You have a few options. Personally, I'd keep all the important (and similar) data for your items in one table, and have 3 columns containing detail IDs, you could then create a couple of different tables containing the extra data for each type and JOIN that data to each query.
Another option is you could have three separate tables containing items, but I don't advise that as it's not good database design practice. If you did want to do that though, you could either select from all three tables in one query:
SELECT * FROM table1, table2, table3
... or manually match the column count using null values and perform a UNION query:
SELECT f1, f2, f3, f4, null as f5 FROM table1
UNION ALL
SELECT f1, f2, f2, null as f4, null as f5 FROM table2
UNION ALL
SELECT f1, f2, f3, f4, f5 FROM table3 -- table 3 contains 5 columns as an example
... but that could get messy as well if you have lots of columns unique to each type. I'd suggest going with three separate tables for each item type's details:
SELECT * FROM items I
LEFT JOIN item_type1 I1 ON I.item1_detail_id = I1.id
LEFT JOIN item_type2 I2 ON I.item2_detail_id = I2.id
LEFT JOIN item_type3 I3 ON I.item3_detail_id = I3.id
Related
I have an Access database that contains 13 tables. The data in the tables are numbers. I would like to be able to relate specific fields in the tables and sum the totals for all of the tables together.
For instance, I have fields for patient information completed in several of the tables the number in the field is the number of patients who completed the form. Each table represents a different facility. The total would represent the number of patients from all of the facilities who completed the form so that I have a grand total.
I'm not sure about how to go about linking the tables.
Thanks,
Gale
These tables do not have relationships - they have the same kind of data, not related data (such as relating Customers to Orders). This is not correct data structure. Should not have a separate table for each facility. Should be one table with another field to ID the facility. Otherwise, UNION query these tables into a single dataset should be in first place.
SELECT ID, F1, F2, F3, "Fac01" AS Facility FROM Table1
UNION SELECT ID, F1, F2, F3, "Fac02" FROM Table2
...
UNION SELECT ID, F1, F2, F3, "Fac13" FROM Table13;
Then use that dataset in subsequent queries, such as GROUP BY or CROSSTAB.
I have a table that has Act ID, and another table that has Act ID, percentage complete. This can have multiple entries for different days. I need the sum of the percentage added for the Act ID on the first tableZA.108381.080
First table
Act ID Percent Date
ZA.108381.110 Total from 2 table
ZA.108381.120
ZA.108476.020
ZA.108381.110 25% 5/25/19
ZA.108381.110 75 6/1/19
ZA.108381.120
ZA.108476.020
This would be generally considering not good practice. Your primary key should be uniquely identifiable for that specific table, and any other data related to that key should be stored in separate columns.
However since an answer is not a place for a lecture, if you want to store multiple values in you Act ID column, I would suggest changing your primary key to something more generic "RowID". Then using vba to insert multiple values into this field.
However changing the primary key late in a databases life may cause alot of issues or be difficult. So good luck
Storing calculated values in a table has the disadvantage that these entries may become outdated as the other table is updated. It is preferable to query the tables on the fly to always get uptodate results
SELECT A.ActID, SUM(B.Percentage) AS SumPercent
FROM
table1 A
LEFT JOIN table2 B
ON A.ActID = B.ActID
GROUP BY A.ActID
ORDER BY A.ActID
This query allows you to add additional columns from the first table. If you only need the ActID from table 1, then you can simplify the query, and instead take it from table 2:
SELECT ActID, SUM(Percentage) AS SumPercent
FROM table2
GROUP BY ActID
ORDER BY ActID
If you have spaces other other special characters in a column or table name, you must escape it with []. E.g. [Act ID].
Do not change the IDs in the table. If you want to have the result displayed as the ID merged with the sum, change the query to
SELECT A.ActID & "." & Format(SUM(B.Percentage), "0.000") AS Result
FROM ...
See also: SQL GROUP BY Statement (w3schools)
I have a query i have been working on trying to get a specific set of data, join the comments in duplicate phone numbers of said data, then join separate tables based on a common field "entry_id" which also happens to be the number on the end of the word custom_ to pull up that table.
table named list and tables containing the values i want to join is custom_entry_id (with entry_id being a field in list in which i need the values of each record to replace the words in order to pull up that specific table) i need entry_id from the beginning part of my query to stick onto the end of the word custom for every value my search returns to get the fields from that custom table designated for that record. so it will have to do some sort of loop i guess? sorry like i said I am at a loss at this point
this is where i am so far:
SELECT * ,
group_concat(comments SEPARATOR '\r\n\r\n') AS comments_combined
FROM list WHERE `status` IN ("SALEA","SALE")
GROUP BY phone_number
//entry_id is included in the * as well as status
// group concat combines the comments if numbers are same
i have also experimented on test data with doing a full outer join which doesnt really exist. i feel if you can solve the other part for me i can do the joining of the data with a query similar to this.
SELECT * FROM test
LEFT JOIN custom_sally ON test.num = custom_sally.num
UNION
SELECT * FROM test
RIGHT JOIN custom_sally ON test.num = custom_sally.num
i would like all of this to appear with every field from my list table in addition to all the fields in the custom_'entry_id' tables for each specific record. I am ok with values being null for records that have different custom fields. so if record 1 has custom fields after the join of hats and trousers and record 2 has socks and shoes i realize that socks and shoes for record 1 will be null and hats and trousers for record 2 will be null.
i am doing all this in phpmyadmin under the SQL tab.
if that is a mistake please advise as well. i am using it because ive only been working with SQl for a few months. from what i read its the rookie tool.
i might be going about this all wrong if so please advise
an example
i query list with my query i get 20,000 rows with columns like status, phone_number, comments, entry_id, name, address, so on.
now i want to join this query with custom fields in another table.
the problem is the custom tables' names are all linked to the entry_id.
so if entry_id is 777 then the custom table fields are custom_777
my database has over 100 custom tables with specials fields for each record depending on its entry_id.
when i query the records I don't know how to join the custom fields that are entry_id specific to the rest of my data.i will pull up some tables and data for a better example
this is the list table:
this is the custom_"entry_id"
Full Outer Join in MySQL
for info on full outer joins.
I have two tables that have different data that I need to merge. They do have similarities such as: Order number, Name, type or product. But they have separate data as well like: Order date, and Engravings.
Would I do two separate Append queries in Access into a merged table? Or one Append queries? Or just keep the data separate?
I am new to Access and trying to find the best way to approach this.
Merging the two tables into one completely defeats the purpose of using a database and you're better off using excel at that point. You want to split the data as much as possible along logical lines so that you can find, say... all the orders that Mr X has ever made for a specific product. And in that case you're going to want to have separate tables for customers, orders, engravings and the like.
The best practice from a design standpoint is to place fields that each table has in common into a third "master" table, then create relationships from that table to the existing tables and delete the data that has been transferred to the main table (except for the primary keys, which have to be common with your master table).
To create the master table, use a Make Table query to generate the master table based on one of your tables, then an append query to add any products in the master table that might not be common to both, based on the other table. Finally, delete queries for each table would rid you of redundant data in both original tables.
However, I strongly suggest you use Microsoft's tutorials and download the NorthWind sample database so you can get an idea of what a properly structured database looks like. The beginner's learning curve for access is very steep and having well built example databases is almost a requisite.
Make a backup of your database(s) and play with it until it turns out right. Do not make the mistake of playing with live data until you know what you're doing.
As you have similar fields on either table, take the Order number field from both tables using a union query. Something like:
SELECT tbl_Delivery_Details.OrderNo
FROM tbl_Delivery_Details
GROUP BY tbl_Delivery_Details.OrderNo
UNION
SELECT tbl_Delivery_Header.[Order number]
FROM tbl_Delivery_Header
GROUP BY tbl_Delivery_Header.[Order number];
This would take the order numbers from the delivery details table and from the delivery header table and merge them into one list with only one instance of each order number. Save the query.
You could then use this query in a new query. Bring in your 2 tables to this query and insert the fields from either table that you require.
As users add records to the tables they will be added to the union selet query when it is next run.
PB
It depends on what you want to do. Let's assume you have tables A (with 50 records) and B (with 75) records, and both tables have a similar column called OrderID.
Appending Rows:
If you want to create a table with 125 total records by combining records (rows) from A and records (rows) from B, run the following two queries:
Query 1:
SELECT A.ORDER_NUMBER, A.TEXT_FIELD1 as DATA INTO C
FROM A;
Query 2:
INSERT INTO C ( ORDER_NUMBER, DATA )
SELECT B.ORDER_NUMBER, B.TEXT_FIELD2
FROM B;
Appending Columns: If you want to create a table with 75 total records where you are appending columns from A to the columns in B, then run the following query:
SELECT B.ORDER_NUMBER, A.TEXT_FIELD1, B.TEXT_FIELD2 INTO C
FROM A RIGHT JOIN B ON A.ORDER_NUMBER = B.ORDER_NUMBER;
... in a similar way, you can append columns in B to columns in A in a new table C with a total of 50 records by running the following query:
SELECT A.ORDER_NUMBER, A.TEXT_FIELD1, B.TEXT_FIELD2 INTO C
FROM A LEFT JOIN B ON A.ORDER_NUMBER = B.ORDER_NUMBER;
I currently have 3 tables,
Users (Id, PositionId)
MonsterInstances (Id, PositionId)
TreasureInstances (Id, PositionId)
and 1 position table.
Positions (Id, Coordinate, TypeId)
PositionId, in my 3 tables, are foreign keys into my Position table.
I want to use a single Positions table, as shown above, to normalize all of my position data. The problem I am facing is that I must identify a type so that when my query executes, it knows which table to query.
e.g.
SP -- GetObjectByPosition (positionId)
IF TypeId = 1
SELECT * FROM Users JOIN... WHERE PositionId = positionId
ELSE IF TypeId = 2
SELECT * FROM MonsterInstances JOIN...
This seems like bad design to me. The only way around it I can percieve would be to have 3 seperate tables.
UserPositions
MonsterInstancePositions
TreasureInstancePositions
However, I'm not always interested in extracting user, monster, or treasure data. Sometimes I only want the position Id and location -- which would mean with three tables, I would have to do a union.
Is there a better way to do this?
Users, MonsterInstances, TreasureInstances could be rewritten as a single "ObjectInstances" table that includes a type column. Then queries that would work against those 3 tables separately would instead work against ObjectInstances and a typeID, referencing a new OjbectTypes table. Make sense?