How to perform join operation when three tables are linked? - sql

I have three tables in database tbProduct, tbCompany, tbCompanyProduct
tbProduct
Product (id feild)
ProductX (product name)
tbCompany
CompanyId
CompanyName
tbCompanyProduct
Company (F.K for Company Id)
Product (F.K for Product Id)
Now I have to perform join operation for fetching all the products assigned to a company i.e on the basis of #companyid parameter...
Please help me !!!

Your query will look like this.....It is simple join between three tables...
SELECT comp.CompanyName, prod.ProductX
FROM tbCompanyProduct compPro
INNER JOIN tbCompany comp ON compPro.Company = comp.CompanyId
INNER JOIN tbProduct prod ON prod.Product = compPro.Product
WHERE comp.CompanyId = yourCompanyId

Related

retrieve data from multiple tables not working

I have three tables
quiz: activetruck:
id id
name name
origin origin
destination destination
total_trucks total_trucks
material_type scheduled_date
scheduled_date offered_price
offered_price owner_id
owner_id subject_id
subject_id
I ran this query to extract the common data from both the tables
Select * from quiz as cq, activetruck as ca
where cq.origin=ca.origin and cq.destination=ca.destination and
cq.subject_id=ca.subject_id and cq.total_trucks<=ca.total_trucks;
there is a third table supplier and supplier is connected to active truck via owner_id
columns of suppliers are:
user_id
supplier_name
supplier_company_name
supplier_email
supplier_gst
supplier_pan
supplier_address
supplier_origin
supplier_service
I want to fetch all the details of supplier where activetruck.owner_id = suppliers.user_id
I tried running this but it didn't work
Select * from classroom_quiz as cq, classroom_activetruck as ca, classroom_supplier as cs
where cq.origin=ca.origin and cq.destination=ca.destination and
cq.subject_id=ca.subject_id and cq.total_trucks<=ca.total_trucks and
ca.owner_id=cs.user_id;
A left outer join is what you need to use. More info here.
The left outer join on activetruck and suppliers will return the suppliers details that match but in the case where there isn't a match it will still return the activetruck rows. Your query is joining where activetruck matches suppliers but if there isn't a match then it doesn't return anything.
SELECT *
FROM classroom_quiz AS cq
INNER JOIN classroom_activetruck ca ON cq.origin = ca.origin
AND cq.destination = ca.destination
AND cq.subject_id = ca.subject_id
AND cq.total_trucks <= ca.total_trucks
LEFT OUTER JOIN classroom_supplier cs ON ca.owner_id = cs.user_id;

Oracle SQL - Sum up and show text if > 0

I'm totally new with Oracle SQL and my question may seem stupid but I have some difficulties to solve my problem.
Current situation:
I have following tables: Supplier, Debtor, Invoice
Every Supplier has various Debtors and every Debtor has various Invoices.
I want to create an evaluation which shows me the following scenario:
A list of all Debtors from a Supplier. I also want to see in that list if the Debtor once haven't payed his invoice. I have this information within the table Invoice as the attribute called "payed" and possible values are 0 (payed) and 1 (not payed). I just want to see the debtor ONCE in the list so if there is only ONE invoice which is 1, it should show me "1" or "Not Payed" in the list. Right now when a debtor has 100 invoices it shows me 100 times the debtor with the info "0" or "1".
Currently:
SELECT company.company_id,
company.companyname_1,
supplier.supplier_id,
supplier.suppliername_1,
debtor.debtor_id_from_supplier,
debtor_ext.debtorname_1,
debtor_ext.street,
debtor_ext.street_number,
debtor_ext.postcode,
debtor_ext.city,
debtor.approved_limit,
debitor.limit_left,
debitor.limit_status,
debitor.limit_type,
debitor.prosecution,
CASE
WHEN invoice.payed = 0 THEN 'Yes'
ELSE 'No'
END as deb_payment
FROM debtor,
debtor_ext,
company,
supplier,
invoice
WHERE ( company.company_id = supplier.company_id ) and
( supplier.supplier_id = debtor.supplier_id ) and
( debtor.debtor_id = debtor_ext.debtor_id ) and
( debtor.supplier_id = invoice.supplier_id ) and
( debtor.debtor_id_from_supplier = invoice.debtor_id_from_supplier )
CODE CORRECTED!
Hope you guys can help me
First of all, In your query, you're doing cross join which is not required and also affects on the performance. I'll advice you to use Inner Join here.
Also,as the schema is not provided in question,I am giving solution for the below schema:
Supplier:
Supplier_Id (PK) | Supplier_Name
Debtor:
Debtor_Id (PK) | Debtor_Name | Supplier_Id (FK)
Invoice:
Invoice_Id (PK) | Supplier_Id (FK) | Debtor_Id (FK) | Amount | Payed
Query:
Select company.company_id,
company.companyname_1,
s.supplier_id,
s.suppliername_1,
d.debtor_id_from_supplier,
d.debtorname_1,
d.street,
d.street_number,
d.postcode,
d.city,
d.approved_limit,
d.limit_left,
d.limit_status,
d.limit_type,
d.prosecution,
tmp.deb_payment
From
(
SELECT d.supplier_id,
d.debtor_id,
(
CASE
WHEN min(i.payed) <> max(i.payed) Then 'Not Payed'
ELSE 'Payed'
END
)as deb_payment
FROM supplier s
inner join debtor d
on s.supplier_id = d.supplier_id
inner join invoice i
on i.supplier_id = d.supplier_id
and i.debtor_id = d.debtor_id
Group by d.supplier_id,d.debtor_id
) tmp
inner join supplier s
on s.supplier_id = tmp.supplier_id
inner join company
on company.company_id = s.company_id
inner join debtor d
on s.supplier_id = d.supplier_id
inner join debtor_ext de
d.debtor_id = de.debtor_id
;
Hope it helps!

Selecting from table with categories of people

I created a database in ms sql , in the database I have three category of persons namely staff, customers, suppliers whom I stored in different tables create serial unique id for each.
Now these persons id are stored under person_id and a column names person type which stores whether its a staff, custimer or supplier in the transaction table, The problem lies in selecting the records from the transaction table like this pseudo code
Select t.*,s.na as staff,sp.name as supplier, c.name as customer
From Trans t
left join Staff s on s.id = t.pid
left join Suppliers sp on sp.id = t.pid
left join Customers c on c.id = t.pid
This returns one row, instead of at least 3 or more, How do I solve this problem
My trans table
person_id Person_type Trans_id
1 staff 1
1 customer 2
2 customer 3
3 suppler 4
1 staff 5
Expected output
person_name Trans_id
james 1
mark 2
dan 3
jude 4
james 5
Staff, Customers, and suppliers are stored in their different tables
That's what the Join does, combine data from multiple tables into one result row. If you want to "keep the rows", not combine them, you can use UNION
(
Select t.* From Trans t
left join Staff s on s.id = t.pid
)
UNION
(
Select t.* From Trans t
left join Suppliers sp on sp.id = t.pid
)
UNION
(
Select t.* From Trans t
left join Customers c on c.id = t.pid
)
This will get you the multiple rows you want BUT still not sure you have defined it right. I see you are only taking columns from Trans, so you're not getting any data from the other tables. And you're doing left outer joins so the other tables won't affect the selection. So I think it's just that same as selecting from just Trans.
If what you want is data from Trans where there is corresponding entry in the other tables, then do the UNION, but also change the outer joins to inner.

How to get distinct and lastest record with inner join query

I have two table named: customers and bill. customer and bill have one to many relation.
Customer table contains record of customer mobileNo,bikeNo etc
Bill table contain record of customer bill with bikeNo(foreign key),billdate etc.
I have query for that:
SELECT customer.mobileNo, bill.iDate AS Expr1
FROM (customer INNER JOIN
bill ON customer.bikeNo = bill.bikeNo)
ORDER BY bill.iDate;
Now How i get distinct and latest billdate record and mobileNo with this query?
Use GROUP BY and MAX():
SELECT customer.mobileNo, MAX(bill.iDate) AS iDate
FROM (customer INNER JOIN
bill ON customer.bikeNo = bill.bikeNo)
GROUP BY customer.mobileNo
ORDER BY iDate

Query Returning SUM of Quantity or 0 if no Quantity for a Product at a given date

I have the following 4 tables:
----------
tblDates:
DateID
30/04/2012
01/05/2012
02/05/2012
03/05/2012
----------
tblGroups:
GroupID
Home
Table
----------
tblProducts:
ProductID GroupID
Chair Home
Fork Table
Knife Table
Sofa Home
----------
tblInventory:
DateID ProductID Quantity
01/05/2012 Chair 2
01/05/2012 Sofa 1
01/05/2012 Fork 10
01/05/2012 Knife 10
02/05/2012 Sofa 1
02/05/2012 Chair 3
03/05/2012 Sofa 2
03/05/2012 Chair 3
I am trying to write a query that returns all Dates in tblDates, all GroupIDs in tblGroups and the total Quantity of items in each GroupID.
I manage to do this but only get Sum(Quantity) for GroupID and DateID that are not null. I would like to get 0 instead. For exemple for the data above, I would like to get a line "02/05/2012 Table 0" as there is no data for any product in "Table" group on 01/05/12.
The SQL query I have so far is:
SELECT tblDates.DateID,
tblProducts.GroupID,
Sum(tblInventory.Quantity) AS SumOfQuantity
FROM (tblGroup
INNER JOIN tblProducts ON tblGroup.GroupID = tblProducts.GroupID)
INNER JOIN (tblDates INNER JOIN tblInventory ON tblDates.DateID = tblInventory.DateID) ON tblProducts.ProductID = tblInventory.ProductID
GROUP BY tblDates.DateID, tblProducts.GroupID;
I reckon I should basically have the same Query on a table different from tblInventory that would list all Products instead of listed products with 0 instead of no line but I am hesitant to do so as given the number of Dates and Products in my database, the query might be too slow.
There is probably a better way to achieve this.
Thanks
To get all possible Groups and Dates combinations, you'll have to CROSS JOIN those tables. Then you can LEFT JOIN to the other 2 tables:
SELECT
g.GroupID
, d.DateID
, COALESCE(SUM(i.Quantity), 0) AS Quantity
FROM
tblDates AS d
CROSS JOIN
tblGroups AS g
LEFT JOIN
tblProducts AS p
JOIN
tblInventory AS i
ON i.ProductID = p.ProductID
ON p.GroupID = g.GroupID
AND i.DateID = d.DateID
GROUP BY
g.GroupID
, d.DateID
use the isnull() function. change your query to:
SELECT tblDates.DateID, tblProducts.GroupID,
**ISNULL( Sum(tblInventory.Quantity),0)** AS SumOfQuantity
FROM (tblGroup INNER JOIN tblProducts ON tblGroup.GroupID = tblProducts.GroupID)
INNER JOIN (tblDates INNER JOIN tblInventory ON tblDates.DateID = tblInventory.DateID)
ON tblProducts.ProductID = tblInventory.ProductID
GROUP BY tblDates.DateID, tblProducts.GroupID;
You don't say which database you're using but what I'm familiar with is Oracle.
Obviously, if you inner join all tbales, you will not get the rows containing nulls. If you use an outer join to the inventory table you also have a problem because the groupid column is not listed in tblinventory and you can only outer join to one table.
I'd say you have two choices. Use a function or have a duplicate of the groupid column in the inventory table.
So, a nicer but slower solution:
create or replace
function totalquantity( d date, g varchar2 ) return number as
result number;
begin
select nvl(sum(quantity), 0 )
into result
from tblinventory i, tblproducts p
where i.productid = p.productid
and i.dateid = d
and p.groupid = g;
return result;
end;
select dateid, groupid, totalquantity( dateid, groupid )
from tbldates, tblgroups
Or, if you include the groupid column in the inventory table. (You can still quarantee integrity using constraints)
select d.dateid, i.groupid, nvl(i.quantity, 0)
from tbldates d, tblinventory i
where i.dateid(+) = d.dateid
group by d.dateid, g.groupid
Hope this helps,
GĂ­sli