I have three tables for a mock/fake database I am creating to learn SQL
Purchases
PK Purchase_ID
FK Creditcard_ID
Order_Date
Products
PK Product_ID
Product
Description
Cost
Purchases_Products
PK Purchases_Products_ID
FK Purchase_ID
FK Product_ID
Quantity
Review
I want to add a View column under Purchases, Total_Cost, that computes this value:
Summation[Product_ID]_(Purchases_Products.Quantity * Products.Cost)
Which sums over all products belonging to a single Purchase_ID. This will require a join. How may I accomplish this?
(edit: While learning how to use a join in a constraint for a Junction Table to prevent null values in parent tables was a great read and something I may want to implement, I still do not understand my question any better sadly.)
Related
I'm creating a clinic management system where I need to store Medical History for a patient. The user can select multiple history conditions for a single patient, however, each clinic has its own fixed set of Medical History fields.
For example:
Clinic 1:
DiseaseOne
DiseaseTwo
DiseaseThree
Clinic 2:
DiseaseFour
DiseaseFive
DiseaseSize
For my Patient visit in a specific Clinic , the user should be able to check 1 or more Diseases for the patient's medical history based on the clinic type.
I thought of two ways of storing the Medical History data:
First Option:
Add the fields to the corresponding clinic Patient Visit Record:
PatientClinic1VisitRecord:
PatientClinic1VisitRecordId
VisitDate
MedHist_DiseaseOne
MedHist_DiseaseTwo
MedHist_DisearThree
And fill up each MedHist field with the value "True/False" based on the user input.
Second Option:
Have a single MedicalHistory Table that holds all Clinics Medical History detail as well as another table to hold the Patient's medical history in its corresponding visit.
MedicalHistory
ClinicId
MedicalHistoryFieldId
MedicalHistoryFieldName
MedicalHistoryPatientClinicVisit
VisitId
MedicalHistoryFieldId
MedicalHistoryFieldValue
I'm not sure if these approaches are good practices, is a third approach that could be better to use ?
If you only interested on the diseases the person had, then storing the false / non-existing diseases is quite pointless. Not really knowing all the details doesn't help getting the best solution, but I would probably create something like this:
Person:
PersonID
Name
Address
Clinic:
ClinicID
Name
Address
Disease:
DiseaseID
Name
MedicalHistory:
HistoryID (identity, primary key)
PersonID
ClinicID
VisitDate (either date or datetime2 field depending what you need)
DiseaseID
Details, Notes etc
I created this table because my assumption was that people have most likely only 1 disease on 1 visit, so in case there's sometimes several, more rows can be added, instead of creating separate table for the visit, which makes queries most complex.
If you need to track also situation where a disease was checked but result was negative, then new status field is needed for the history table.
If you need to limit which diseases can be entered by which clinic, you'll need separate table for that too.
Create a set of relational tables to get a robust and flexible system, enabling the clinics to add an arbitrary number of diseases, patients, and visits. Also, constructing queries for various group-by criteria will become easier for you.
Build a set of 4 tables plus a Many-to-Many (M2M) "linking" table as given below. The first 3 tables will be less-frequently updated tables. On each visit of a patient to a clinic, add 1 row to the [Visits] table, containing the full detail of the visit EXCEPT disease information. Add 1 row to the M2M [MedicalHistory] table for EACH disease for which the patient will be consulting on that visit.
On a side note - consider using Table-Valued Parameters for passing a number of rows (1 row per disease being consulted) from your front-end program to the SQL Server stored procedure.
Table [Clinics]
ClinicId Primary Key
ClinicName
-more columns -
Table [Diseases]
DiseaseId Primary Key
ClinicId Foreign Key into the [Clinics] table
DiseaseName
- more columns -
Table [Patients]
PatientId Primary Key
ClinicId Foreign Key into the [Clinics] table
PatientName
-more columns -
Table [Visits]
VisitId Primary Key
VisitDate
DoctorId Foreign Key into another table called [Doctor]
BillingAmount
- more columns -
And finally the M2M table: [MedicalHistory]. (Important - All the FK fields should be combined together to form the PK of this table.)
ClinicId Foreign Key into the [Clinics] table
DiseaseId Foreign Key into the [Diseases] table
PatientId Foreign Key into the [Patients] table
VisitId Foreign Key into the [Visits] table
I have an order with details such customer id, order date, order type etc...
The order then contains a list of products on that order
Do I create one table for the order and then another table for the products?
If so, should there then be foreign keys between the 2 tables?
Here's how I'd model it:
Customer can have many Orders; an Order belongs to one Customer.
An Item refers to one Product
An Order can have many Items; an Item belongs to one Order.
One-to-many foreign keys always belong in the "many" table and refer back to their "one" table.
If you have many to many relationships you need a JOIN table, which has two one-to-many foreign keys.
You current condition may works if the product is not belong to your store/source , you are getting products from different source and client order the product so you can maintain the order with the require details.
if the product came from your source/store then you must need the product and order
Your table structure should look like below. In your product table create a reference to order_id in order table by means of foriegn key. Thatway, each order will be associated
with one or more products and you can find out the same using a JOIN in your SELECT query.
Table: Order(order_id Primary key,customer id, order date, order type)
Table: Products(product_id primary key, order_id foriegn key,col1, col2);
Explanation:
A product may not be associated with a order at all time but a order must be associated with a product (Obhious reason, we can't have a blank order).
I am creating a relationship between 2 tables:
The relationship I like to form is between the Inventory an InventoryExtended tables.
The primary key for the Inventory table is InvID (Inventory ID).
The reason why I created the InventoryExtended is becauses only 1% of the inventory items in the Inventory table will need additional or extended fields, the rest will not.
Instead of adding these additional fields in the Inventory table where 99% will be blank for 50 additional fields that I need I decided to create an InventoryExtended table and store the 50 fields there.
The relationship between the Inventory an InventoryExtended table will be 1 to 1.
Meaning, for the 1% of the records in the Inventory table , the InvId will be the same as the InvId in the InventoryExtended table.
My question is that should the InvID in the InventoryExtended table be a FK (Foreign Key) or should it be a PK and a FK?
I am thinking it should be a PK and a FK as there the InvID will be unique in the InventoryExtended table.
Thanks in advance.
You are correct.
The InvID should be a PRIMARY KEY and a FOREIGN KEY as it will be unique in the InventoryExtended table.
This type of relationship is indeed 1:1 or (more accurately) 1::0..1, as only some of the rows in the Inventory table will have a related row in InventoryExtended.
Also note that the InventoryExtended (InvID) should not have the IDENTITY property, even if the Inventory (InvID) has it.
The InvID will be both a PK and FK for the extended table.
If you know in advance (meaning when you attempt to fetch data) whether or not a particular inventory type will have the extended data, for such records you can even skip the original table altogether and simply use two disjoint tables smallInventory and bigInventory such that no records of one are present in the other.
I have a table that contains all products. There are 3 distinct types of products so these have their own tables, lets say ProductType1, ProductType2, ProductType3.
There is a 1-1 relationship between Products and ProductType(n) on ProductId, but to further constraint the child tables there is an additional relationship using a ProductId, ProductTypeId in Products, and a ProductId, ComputedProductTypeId in each of the other tables.
This ensures that a product can only be added to a single matching ProductType table.
The question is this. As there is already a relationship between the 2 tables on ProductId, rather than using an index for the FK, can I get away with a unique key to constrain the relationship, or will this cause performance issues?
Products
PK ProductId
FK ProductId, ProductTypeId
^
*Add an index for this or unique key constraint?*
ProductType(n)
PK ProductId
FK ProductID, ComputedProductTypeId (fixed int)
Creating an index will be better approach.
If you want to delete entries from your master table, SQL server looks for FK relations if any exists. So Creating Index on your composite key (which includes FK) will speed up the process.
im developing a simple access application that helps us to order the right products for a project. i have a table for each contractor containing its products. i have a table "favorite-products" that relates to products and gives additional information how and when they should be used.
normally id have a big table (containing all products) that has a contractor-column. i my favorite-products table i could then easyly relate to a product. but here i need to keep the products in separate tables. so whats the best way to connect my favorite-products table with the products in the contractor-tables?
thanks :)
This is not the best design.
You should UNION all contractor tables together and JOIN with the result:
SELECT *
FROM (
SELECT product
FROM contractor1
UNION ALL
SELECT product
FROM contractor2
UNION ALL
…
) c
JOIN favorite f
ON f.product = c.product
You better keep one single table for you products with contractor as a field.
It will be much easier to query and to manage.
I would create a contractors table, a product table and then a many-to-many linked table contractors to products. Also i would create a favorite-products table in which you can also have a many-to-many contractors to products link for those cases where a product can come from more than 1 contractor
So, you'll have a Contractor, Product and Contractor_Product table. Something like (in psuedo-sql):
create table Contractor {
id int primary key,
name varchar(50) not null,
...
}
create table Product {
id int primary key,
name varchar(50) not null,
...
}
create table Contractor_Product {
contractorid int references Contractor(id),
productid int references Product(id),
...,
primary key contractorid, productid
}
Now, I'm not 100% sure what you want from the "Favorites" table. It may not be a table, but rather a query. Or, maybe you want a table that similar to the Contractor_Product table? Or just another "isfavorite bool default=false" column on the Contractor_Product table?
Hope that helps!