How can I query these 4 tables by joining them? - mysql

Could someone help me and teach me to query this. Please..
Pawner table
Item table
loan_assignment table
Loan table
When I join those 4 tables the result should be like this
I had queried this but the result is redundant.
This is my query:
SELECT a.date_loan_granted, p.pawner_id, p.name, c.item_name, l.principal_loan
FROM loan_assignment a
JOIN pawner p ON p.pawner_id = a.pawner_id
JOIN item c ON c.item_id = a.item_id
JOIN loan l ON l.loan_id = a.loan_id;
The result of this query above ^ is this

To fix your issue: In loan_assignment set the loan_id for 500 to 1 and 300 to 2. then on loan the value that is null for payment set the loan_id to 1 and the one with 200 set the loan_id to 2. should clear up your issue once you use distinct.
Your parent child relationship for these tables goes as follows
Pawner
PK: Pawner_ID
FK: Pawnshop_ID
Loan_assignment
PK: None
FK: Pawnshop_ID, Pawner_ID, Item_ID, Loan_ID
Item
PK: Item_ID
Loan
PK: Loan_ID
Right now structure should be:
A Pawn Shop can have multiple pawners.
A Pawner can have multiple loans.
A Loan can have one or many items.
An Item can have multiple payments.
here are some suggestions to fix your tables since using a distinct is not good enough to resolve your structure issue.
Loan Assignment: all loans belong to a pawnshop and a pawner (why not just have them belong to a pawner and remove the pawnshop since that information is redundant and can be found from the parent child relationship). This table needs its own primary key because each loan is treated different. This table should have the inital loan in it with the amount all the rest of the transactions that your trying to do here should be moved to a payment table with a PK of its own and a FK back to the loan it belongs to.
Item Table: The Item_ID field is the primary key for this table. the values need to be unique because each item is a piece of inventory you need to treat separate. you may want a FK in this table linking it back to the Loan Assignment so that a loan can have multiple items assigned to it.
Loan: this table needs to have some information moved to the loan table and some moved to the suggested payment table.
The table structure is not solid for what you would like to do. i recommend at this point going online and looking at the parent child relationship for a loan or pawn shop database that exists and working from that.

I think this would do it for you, althought, NOTE* i belive you are missing a column from your description of the table LOAN_Assignment (pawner_id)
SELECT a.date_loan_granted, p.pawner_id, p.name, c.item_name, l.principal_loan
FROM loan_assignment a
JOIN loan l ON l.loan_id = a.loan_id;
JOIN pawner p ON p.pawner_id = l.pawner_id
JOIN item c ON c.item_id = a.item_id

Related

Designing a mysql database of relationships between contacts?

I'm trying to design a database of contacts but I also want to keep track of their relationships with other contacts whether it be family, friends, cowokers etc. I created a table for contacts and created an affiliates table that labels the type of relationship but I'm not sure if I did the design correct and I'm unsure if this would just be a normal many to many relationship or some sort of recursive relationship. I would also like to know how I would query to be able to get all the relationships to one contact and all of the relationships to all contacts.
Contacts Table
CID CFirstName CLastName
1 Roy Saldana
2 Linda Rodriguez
3 Hector Rodriguez
Both CID & C_ID are the same I just thought I couldn't name both columns the same so I gave one a _.
Affiliates Table
CID AfiliateType C_ID ex: CID is the mother of C_ID 1
2 mother 1
1 son 2
3 husband 2
3 step-father 1
3 wife 3
SELECT Contacts.FirstName, Contacts.LastName, Afiliates.AfiliateType
FROM Contacts
INNER JOIN Afiliates
ON Contacts.CID = Afiliates.C_ID
I know this isn't the correct way but I can't seem to get passed this part, I'm thinking I need to query the names twice or maybe it's a programming issue not the design, I'm totally lost. Any help would be appreciated. Thanks in advance
-- Contact CID is named FIRST_NAME LAST_NAME.
--
contacts {CID, FIRST_NAME, LAST_NAME}
PK {CID}
AK {FIRST_NAME, LAST_NAME}
-- Contact CID_1 is AFF_TYPE of contact CID_2.
--
affiliates {CID_1, CID_2, AFF_TYPE}
PK {CID_1, CID_2}
FK1 {CID_1} REFERENCES contacts {CID}
FK2 {CID_2} REFERENCES contacts {CID}
CHECK (CID_1 <> CID_2)
Contact FROM_FIRST FROM_LAST is AFF_TYPE of TO_FIRST TO_LAST.
SELECT b.FIRST_NAME AS FROM_FIRST
, b.LAST_NAME AS FROM_LAST
, a.AFF_TYPE
, c.FIRST_NAME AS TO_FIRST
, c.LAST_NAME AS TO_LAST
FROM affiliates AS a
JOIN contacts AS b ON b.cid = a.cid_1
JOIN contacts AS c ON c.cid = a.cid_2
WHERE a.cid_1 = the_contact_id
OR a.cid_2 = the_contact_id ;
One thing to consider is what to do with symmetrical relations, for example
CID_1 is mother of CID_2, is not symmetrical, but CID_1 is sibling of CID_2 is.
For symmetrical relations it is the usual way to insert rows only for CID_1 < CID_2.
Note:
All attributes (columns) NOT NULL
PK = Primary Key
AK = Alternate Key (Unique)
FK = Foreign Key
Yes, you need to query the names twice. Once for the Contact and a second time for their affiliate:
SELECT c.FirstName, c.LastName, a.AfiliateType, ac.FirstName AS AffiliateFirstName, ac.LastName AS AffiliateLastName
FROM Contacts c LEFT JOIN Afiliates a ON c.CID = a.C_ID
LEFT JOIN Contact ac ON a.CID = ac.CID
The key is to set up an alias for the Contacts table to use it a second time as the Affiliate Contact.
Please note, I didn't test this, so I might have made a slight error, but I hope it gives you the idea.

How to get Data from three tables in one query where table 2 contains foreign keys from table 1 and 3

I want to get all the suppliers for one product with product details for which I am using following tables.
I have one Table products with columns
id(pk)
name
type
second table product_supplier with columns
psid(pk)
pid(fk from products)
sid(fk from supplier)
third table supplier with columns
id(pk)
firstname
lastname
I want to get data from these three tables in one mysql query.
Is this what you are looking for?
select p.*, s.*
from products p
inner join product_supplier ps on ps.pid = p.id
inner join supplier s on s.id = ps.sid
order by p.id, s.id
This will return each product along with all the associated suppliers.

Is it a join in SQL?

I have three tables.
The first table is:
Orders
======
Ordernumber PK
CartID
Field1
....
The second table is:
OrderDetails
============
Ordernumber PK
SKU FK (with InventorySuppliers localSKU field)
Field-a
.....
The third table is:
InventorySuppliers
=================
SupplierID PK
LocalSKU FK (Orderdetails table with 'SKU')
Field-x
....
I want to do is something like this:
SELECT *
FROM ORDERS
WHERE ORDERS.CARTID = 11
AND INVENTORYSUPPLIER.SUPPLIERID = 155
My problem is that there is no direct relation between the two tables used in this query.
How can I write this query?
Yes, you need a JOIN:
SELECT o.*
FROM orders o
JOIN orderdetails od ON o.ordernumber = od.ordernumber
JOIN inventorySuppliers is ON is.localSKU = od.SKU
WHERE o.cartID = 11
AND is.supplierID = 155
Because there is no direct relationship between orders and inventorySuppliers tables records, you have to use the third table (orderdetails) to join them together.
Your schema design is fatally flawed, because two different suppliers may use the same sku for different products. Your schema provides no way to know which record in the inventory suppliers the sku refers to.
Before you can do anything else with this sql, you need to change the schema to include supplierID in the order details records.

Inverse of Inner join (Intersect) with multiple foreign keys

Hi I want to get opposite of intersect from two tables.
I have a sale table and purchase table. What I want to do is get all purchases ids where not included in the sales table.
sale table
sale_id (pk)
product_id (fk)
purchase_id (fk)
purchase table
product_id (fk)
purchase_id (pk)
SELECT DISTINCT purchase_id
, product_id
FROM
purchase
INNER JOIN sale
USING (purchase_id, product_id);
Here is an example:
If I run the above code, this will be the result.
purchase_id product id
1 1
1 2
1 4
2 1
2 3
Now I want to get:
purchase_id product id
1 3
2 2
In short I want to get inverse of above code. Thanks in advance.
Okay, I think I understand better now.
This should return any entry in purchase that have no matching entry in sales.
SELECT
`purchase`.`purchase_id`, `purchase`.`product_id`
FROM `purchase`
LEFT JOIN `sale` ON `sale`.`purchase_id` = `purchase`.`purchase_id` AND `sale`.`product_id` = `purchase`.`product_id`
WHERE
`sale`.`sale_id` IS NULL
ORDER BY
`purchase`.`purchase_id`, `purchase`.`product_id`
If you want to get all the purchases that have no related values in the sales table, you can use a LEFT JOIN:
select
p.purchase_id
from
purchase as p
left join sale as s on p.purchase_id = s.purchase_id
where
s.purchase_id is null;
"Unilateral" joins (LEFT JOIN, RIGHT JOIN) are useful when you want to get data from a table even if data in another related table does not exist. Of course, that means that you can filter data from one table when there's no related data in a second table.
Hope this helps.
Looking at your updated question and your comment, I think that you want all the possible combinations not used.
You'll need to split this in two steps:
First you need all the possible combinations of purchase_id and sale_id values (the "cartesian product" of both the sets).
Then you need to get all the combinations already used.
Finally you need to exclude all the combinations already used.
This can be done using subqueries.
Step 1.
select distinct p.purchase_id, s.product_id from purchase as p, sale as s;
Step 2. (Your query)
select distinct
purchase_id, product_id
from
purchase as p
inner join sale as s
on (p.purchase_id = s.purchase_id and p.product_id = s.product_id);
Step 3. Put it all together
select
a.*
from
(select distinct p.purchase_id, s.product_id from purchase as p, sale as s) as a
left join (
select distinct
purchase_id, product_id
from
purchase as p
inner join sale as s
on (p.purchase_id = s.purchase_id and p.product_id = s.product_id)
) as e on (a.purchase_id = e.purchase_id and a.product_id = e.product_id)
where
e.purchase_id is null and e.product_id is null;

how do I fix this MySQL DELETE query?

I have three tables, products, shops, and sex. I wish to DELETE rows in the products table having a product_id such that there exists no equivalent product_id in the sex table.
Further, these rows in the products table must have a shop_id equal to the shop_id in the shops table for the row whose shops.shop value is 'www.shop.com'.
so far I have
DELETE FROM products USING shops WHERE
products.shop_id=shops.shop_id AND
shops.shop='www.shop.com' AND NOT EXISTS
(SELECT sex.product_id FROM sex WHERE
sex.product_id=products.product_id)
but it appears it is not acceptable to make reference to products in the subquery as I have done. (I get the error Unknown table 'products' in MULTI DELETE.) How do I fix my mistake?
You can use JOINs in your DELETE statement:
DELETE a
FROM products a
JOIN shops b ON a.shop_id = b.shop_id AND b.shop = 'www.shop.com'
LEFT JOIN sex c ON a.product_id = c.product_id
WHERE c.product_id IS NULL
This will DELETE only the products which have a corresponding row in the shops table with shop = www.shop.com, but only if that product also does not have a corresponding row in the sex table.