Cust_id| Name |Ord_no|Ord_Date |PROD-ID|Descr |Qty_ord|
C001 | Pink | O81 | 15-Apr |P005 |Chisel|6 |
C001 | Pink | O81 | 15-Apr |P004 |Jane |14 |
C0075 | Red | O99 | 16-Apr |P015 |Saw |3 |
C009 | Black| O56 | 16-Apr |P033 |Punch |24 |
C009 | Black| O56 | 16-Apr |P004 |Jane |9 |
C001 | Pink | O88 | 17-Apr |P015 |Saw |10 |
From this table example I am trying to understand both this dependencies. According to me partial dependencies have a primary composite key and transitive don't have.
I think Primary key are Ord_no and Prod_id.Not sure about Cust_id
The only non key column which depends on the whole key is Quantity. All the rest are partial dependencies.Not sure about Transitive dependency exist or not in this table
Partial Dependency in the table are :
• Cust_id and Name
• Prod_id and Decr
Also the Transitive Dependency in the table are as follow :
• Ord no_ and Ord_date can be ?
Update 1-I try to figure out but not sure about my answer.
I just want clarification like order no is unique, and determines the customer so how can two different order_no 81 & 88 can have same customer id C001.
Therefore I think no transitive dependency.
I see many dependencies in your current table which could be refactored:
The Cust_id most likely determines the customer name
The Ord_no determines the set of products included in that order
The PROD-ID determines the description of that product
I would suggest the following schema, involving four tables:
Customers
Cust_id (PK) | Name
C001 | Pink
C009 | Black
C0075 | Red
Products
PROD-ID (PK) | Descr
P004 | Jane
P005 | Chisel
P015 | Saw
P033 | Punch
Orders
Ord_no (PK) | Ord_Date | Cust_id
056 | 16-APR | C009
081 | 15-APR | C001
088 | 18-APR | C001
099 | 16-APR | C0075
OrdersDetails
Ord_no | PROD-ID | Qty-ord (primary key is Ord_no, PROD-ID)
O56 | P004 | 9
O56 | P033 | 24
O81 | P004 | 14
O81 | P005 | 6
O88 | P015 | 10
O99 | P015 | 3
Now if you want the current output you have, you can obtain it via a join query:
SELECT
c.Cust_id,
c.Name,
o.Ord_no,
o.Ord_Date,
od.PROD-ID,
p.Descr,
od.Qty-ord
FROM Customers c
INNER JOIN Orders o
ON c.Cust_id = o.Cust_id
INNER JOIN OrdersDetails od
ON o.Ord_no = od.Ord_no
INNER JOIN Products p
ON od.PROD-ID = p.PROD-ID;
Related
I'm working on my senior High School Project and am reaching out to the community for help! (As my teacher doesn't know the answer to my question).
I have a simple "Products" table as shown below:
I also have a "Orders" table shown below:
Is there a way I can create a field in the "Orders" table named "Total Cost", and make that automaticly calculate the total cost from all the products selected?
Firstly, I would advise against storing calculated values, and would also strongly advise against using calculated fields in tables. In general, calculations should be performed by queries.
I would also strongly advise against the use of multivalued fields, as your images appear to show.
In general, when following the rules of database normalisation, most sales databases are structured in a very similar manner, containing with the following main tables (amongst others):
Products (aka Stock Items)
Customers
Order Header
Order Line (aka Order Detail)
A good example for you to learn from would be the classic Northwind sample database provided free of charge as a template for MS Access.
With the above structure, observe that each table serves a purpose with each record storing information pertaining to a single entity (whether it be a single product, single customer, single order, or single order line).
For example, you might have something like:
Products
Primary Key: Prd_ID
+--------+-----------+-----------+
| Prd_ID | Prd_Desc | Prd_Price |
+--------+-----------+-----------+
| 1 | Americano | $8.00 |
| 2 | Mocha | $6.00 |
| 3 | Latte | $5.00 |
+--------+-----------+-----------+
Customers
Primary Key: Cus_ID
+--------+--------------+
| Cus_ID | Cus_Name |
+--------+--------------+
| 1 | Joe Bloggs |
| 2 | Robert Smith |
| 3 | Lee Mac |
+--------+--------------+
Order Header
Primary Key: Ord_ID
Foreign Keys: Ord_Cust
+--------+----------+------------+
| Ord_ID | Ord_Cust | Ord_Date |
+--------+----------+------------+
| 1 | 1 | 2020-02-16 |
| 2 | 1 | 2020-01-15 |
| 3 | 2 | 2020-02-15 |
+--------+----------+------------+
Order Line
Primary Key: Orl_Order + Orl_Line
Foreign Keys: Orl_Order, Orl_Prod
+-----------+----------+----------+---------+
| Orl_Order | Orl_Line | Orl_Prod | Orl_Qty |
+-----------+----------+----------+---------+
| 1 | 1 | 1 | 2 |
| 1 | 2 | 3 | 1 |
| 2 | 1 | 2 | 1 |
| 3 | 1 | 1 | 4 |
| 3 | 2 | 3 | 2 |
+-----------+----------+----------+---------+
You might also opt to store the product description & price on the order line records, so that these are retained at the point of sale, as the information in the Products table is likely to change over time.
I have two tables document and documentd the first one contains the numbers of the documents 'doc_num' primary key, document types 'doc_type' (FACA, BLCO, BLCM, BLCK .....) and the document date 'doc_date'
MANY DOCUMENTS DIFFERENT DATES AND DIFFERENT TYPES
Table DOCUMENT:
| DOC_NUM | DOC_TYPE | DOC_DATE |
| | | |
| ACHAT190122001 | FACA | 22/01/2019 |
| ACHAT190222001 | FACA | 22/02/2019 |
| ACHAT190322001 | FACA | 22/03/2019 |
| BLCO190122001 | BLCO | 22/01/2019 |
| BLCO190123001 | BLCO | 23/01/2019 |
| BLCM190122001 | BLCM | 22/01/2019 |
| ACHAT190102010 | FACA | 02/01/2019 |
| ACHAT190103011 | FACA | 03/01/2019 |
| ACHAT190422005 | FACA | 22/04/2019 |
DOCUMENT TABLE
The second table contains as foreign key 'doc_num' the articles of each document 'art_code' and finally the prices of the articles 'art_prix'.
DETAILS OF EACH DOCUMENTS IN DOCUMENT TABLE WITH DIFFERENT AND SAME ARTICLES AND PRICES.
Table DOCUMENTD:
| DOC_NUM | ART_CODE |ART_PRIX |
| | | |
| ACHAT190122001 | ARTICLE1 | 1000 |
| ACHAT190122001 | ARTICLE2 | 2000 |
| ACHAT190102010 | ARTICLE1 | 950 |
| ACHAT190103011 | ARTICLE1 | 980 |
| ACHAT190422005 | ARTICLE2 | 1200 |
| ACHAT190120006 | ARTICLE2 | 1000 |
| BLCO190122001 | ARTICLE1 | 900 |
| BLCO190123001 | ARTICLE2 | 800 |
DOCUMENTD TABLE
My goal is to join the two tables using 'doc_num' selects all BLC type documents and their articles except the prices they must be THE LAST UPDATED PRICE IN FCAC TYPE FOR EXAMPLE
RESULT:
| BLCO190122001 | ARTICLE1 | 1000 | 22/01/2019 |
| BLCO190123001 | ARTICLE2 | 1200 | 22/04/2019 |
RESULT
As I see it, you want to join all the FACA type documents with all the BLC? documents on the ART_CODE column.
I'm certain it can be done with a single SQL query, but for me it's easier to do it as follows.
Create a view for all the FACA type documents...
create view FACAS as
select DOCUMENTD.DOC_NUM, DOCUMENTD.ART_CODE, DOCUMENTD.ART_PRIX, DOCUMENT.DOC_DATE
from DOCUMENTD join DOCUMENT on DOCUMENTD.DOC_NUM = DOCUMENT.DOC_NUM
where DOCUMENT.DOC_TYPE = 'FACA'
Create another view for all the BLC? type documents...
create view BLC_S as
select DOCUMENTD.DOC_NUM, DOCUMENTD.ART_CODE, DOCUMENTD.ART_PRIX, DOCUMENT.DOC_DATE
from DOCUMENTD join DOCUMENT on DOCUMENTD.DOC_NUM = DOCUMENT.DOC_NUM
where DOCUMENT.DOC_TYPE like 'BLC%'
Now query both views, joining on the ART_CODE column...
select BLC_S.DOC_NUM, BLC_S.ART_CODE, FACAS.ART_PRIX, BLC_S.DOC_DATE
from FACAS join BLC_S on FACAS.ART_CODE = BLC_S.ART_CODE
Here's one way:
DECLARE #document table (
DOC_NUM VARCHAR(MAX)
,DOC_TYPE VARCHAR(MAX)
,DOC_DATE VARCHAR(MAX)
)
INSERT INTO #document VALUES
('ACHAT190122001', 'FACA', '22/01/2019')
, ('ACHAT190222001', 'FACA', '22/02/2019')
, ('ACHAT190322001', 'FACA', '22/03/2019')
, ('BLCO190122001', 'BLCO', '22/01/2019')
, ('BLCO190123001', 'BLCO', '23/01/2019')
, ('BLCM190122001', 'BLCM', '22/01/2019')
DECLARE #documentd TABLE (
DOC_NUM VARCHAR(MAX)
,ART_CODE VARCHAR(MAX)
,ART_PRIX SMALLMONEY
)
INSERT INTO #documentd VALUES
('ACHAT190122001', 'ARTICLE1', 1000)
,('ACHAT190122001', 'ARTICLE2', 2000)
,('BLCO190122001', 'ARTICLE1', 900)
,('BLCO190123001', 'ARTICLE2', 800)
SELECT d1.DOC_NUM, dd1.ART_CODE, dd2.ART_PRIX, d2.DOC_DATE from #document d1
INNER JOIN #documentd dd1 ON dd1.DOC_NUM = d1.DOC_NUM
INNER JOIN #documentd dd2 ON dd2.ART_CODE = dd1.ART_CODE
INNER JOIN #document d2 ON d2.DOC_NUM = dd2.DOC_NUM AND d2.DOC_TYPE <> d1.DOC_TYPE
WHERE d1.DOC_TYPE = 'BLCO'
This returns:
DOC_NUM ART_CODE ART_PRIX DOC_DATE
BLCO190122001 ARTICLE1 1000.00 22/01/2019
BLCO190122001 ARTICLE2 2000.00 22/01/2019
From your example results, I assumed you wanted only the BLCO documents and not the BLCM. If you want both, just change the last line to be:
WHERE d.DOC_TYPE LIKE 'BLC%' AND d2.DOC_TYPE = 'FACA'
I am trying to run a query in Oracle Developer that is going to pull specific data from multiple tables and join it into one table with results.
Please find sample code below:
select distinct tbl1.Product_ID, tbl2.Supplier_ID
from tbl3
inner join tbl1
on tbl1.Product_ID = tbl3.Product_ID
inner join tbl2
on tbl3.PO_ID = tbl2.PO_ID
where tbl1.Season_ID LIKE 'AA18'
order by tbl1.Product_ID
The result is as expected:
+------------------+---------------+
| Product ID | Supplier_ID |
+------------------+---------------+
| ID-1 | NHII88 |
| ID-2 | NHII88 |
| ID-3 | NHII88 |
| ID-4 | NHII88 |
| ID-5 | NHII88 |
+------------------+---------------+
Explanation: Distinct is required at this point as without this call multiple Product_ID's (ie ID-1) will be diplayed due to multiple PO's.
Result I am trying to achieve is as per below:
+------------------+---------------+
| Product ID | Supplier_ID |
+------------------+---------------+
| ID-1 | NHII88 |
| ID-1 | LLLLPP |
+------------------+---------------+
+------------------+---------------+
| Product ID | Supplier_ID |
+------------------+---------------+
| ID-4 | NHII88 |
| ID-4 | LLLLP |
| ID-4 | KKKOOP |
+------------------+---------------+
It doesn't exactly need to be grouped in this way, but the idea is to display only duplicate records within this query.
I have been trying to use HAVING, but I must have done something wrong as this has returned same result as per example one.
Many thanks in advance for any suggestions.
Data example:
Tbl1
+------------------+---------------+
| Product ID | Season_ID |
+------------------+---------------+
| ID-4 | AA18 |
| ID-4 | AA17 |
| ID-4 | AA16 |
+------------------+---------------+
Tbl2
+------------------+---------------+
| PO_number | Supplier_ID |
+------------------+---------------+
| PO1234 | NHII88 |
| PO1235 | LLLLPP |
| PO1236 | KKKOOP |
+------------------+---------------+
Tbl3
+------------------+---------------+
| PO_number | Product_ID |
+------------------+---------------+
| PO1234 | ID-1 |
| PO1235 | ID-2 |
| PO1236 | ID-3 |
+------------------+---------------+
My business rules are this.
tbl1 contains all details about products, such as Product_ID and Season_ID (ID-1 and AA18). tbl2 contains PO header details such as PO number and Supplier_ID. tbl3 contains Purchase Order Line details such as PO number and Product_ID.
The idea is to pull all PO numbers from tbl3 where Product_ID in that table = Product_Id in tbl1 and Season_ID = AA18. Other Products should be ignored. If result match PO number detail from tbl3 should be referenced into tbl2 where Supplier_ID can be found.
Expecting results as mentioned above.
The posted sample data doesn't contain any duplicates so it's a bit difficult to see why your required output looks the way it does. However, this implements your posted business rules:
select tbl1.Product_ID
, tbl2.Supplier_ID
from tbl1
inner join tbl3 on tbl1.Product_ID = tbl3.Product_ID
inner join tbl2 on tbl3.PO_number = tbl2.PO_number
where tbl1.Season_ID = 'AA18'
I have a database table that has a companion many-to-many self-join table alongside it. The primary table is part and the other table is alternate_part (basically, alternate parts are identical to their main part with different #s). Every record in the alternate_part table is also in the part table. To illustrate:
`part`
| part_id | part_number | description |
|---------|-------------|-------------|
| 1 | 00001 | wheel |
| 2 | 00002 | tire |
| 3 | 00003 | window |
| 4 | 00004 | seat |
| 5 | 00005 | wheel |
| 6 | 00006 | tire |
| 7 | 00007 | window |
| 8 | 00008 | seat |
| 9 | 00009 | wheel |
| 10 | 00010 | tire |
| 11 | 00011 | window |
| 12 | 00012 | seat |
`alternate_part`
| main_part_id | alt_part_id |
|--------------|-------------|
| 1 | 5 | // Wheel
| 5 | 1 | // |
| 5 | 9 | // |
| 9 | 5 | // |
| 2 | 6 | // Tire
| 6 | 2 | // |
| ... | ... | // |
I am trying to produce a simple SQL query that will give me a list of all alternates for a main part. The tricky part is: some alternates are only listed as alternates of alternates, it is not guaranteed that every viable alternate for a part is listed as a direct alternate. e.g., if 'Part 3' is an alternate of 'Part 2' which is an alternate of 'Part 1', then Part 3 is an alternate of Part 1 (even if the alternate_part table doesn't list a direct link). The reverse is also true (Part 1 is an alternate of Part 3).
Basically, right now I'm pulling alternates and iterating through them
SELECT p.*, ap.*
FROM part p
INNER JOIN alternate_part ap ON p.part_id = ap.main_part_id
And then going back and doing the same again on those alternates. But, I think there's got to be a better way.
The SQL query I'm looking for will basically give me:
| part_id | alt_part_id |
|---------|-------------|
| 1 | 5 |
| 1 | 9 |
For part_id = 1, even when 1 & 9 are not explicitly linked in the alternates table.
Note: I have no control whatever over the structure of the DB, it is a distributed software solution.
Note 2: It is an Oracle platform, if that affects syntax.
You have to create hierarchical tree , probably you have to use connect by prior , nocycle query
something like this
select distinct p.part_id,p.part_number,p.description,c.main_part_id
from part p
left join (
select main_part_id,connect_by_root(main_part_id) real_part_id
from alternate_part
connect by NOCYCLE prior main_part_id = alternate_part_id
) c
on p.part_id = c.real_part_id and p.part_id != c.main_part_id
order by p.part_id
You can read full documentation about Hierarchical queries at http://docs.oracle.com/cd/B28359_01/server.111/b28286/queries003.htm
I read from a classmate post:
“Joins are usually done using primary keys in a good database design.”
Is really using primary keys as predicate necessary for good design. I can't see how.
Thank you for your help!
Use of primary keys for a good database design could be a debate. classically according to RDBMS guideline it is recommended to create primary keys for good database design. but now a days there is a trend not to put much constraints on DB side to improve performance rather do the validations on business layer (not sure if it is true for primary keys as well).
Now coming to your question,
Primary keys are not mandatory for join operations, however it is mandatory to use columns which uniquely identifies the records of master table otherwise it can generate spurious records.
department
| dept| sub_dept | dsc |
| CS | CS | Computer sc.|
| CS | IT | Info Tech. |
student
| Name | age | sex | dept | sub_dept|
| abcd | 025 | M | CS | CS |
| wxyz | 023 | M | CS | IT |
Now if you join the tables on sub_dept you will get correct results.
select s.name, s.age, s.sex, d.dsc from student s, department d where
s.sub_dept = d.sub_dept
| Name | age | sex | dsc |
| abcd | 025 | M | Computer Sc. |
| wxyz | 023 | M | Computer Sc. |
if you join the tables on dept column you will get spurious tuples (2 extra rows)
select s.name, s.age, s.sex, d.dsc from student s, department d where s.dept = d.dept
| Name | age | sex | dsc |
| abcd | 025 | M | Computer Sc. |
| wxyz | 023 | M | Computer Sc. |
| abcd | 025 | M | Info Tech. |
| wxyz | 023 | M | Computer Sc. |