Join multiple tables in a ternary - sql

I have a 3 tables (customers, customerID is PK)(services, serviceID is PK)(equipment, equID is PK). The second two tables have a cost associated with them. All 3 tables connect individually to a table (Billing, transID is the PK). Another process puts transactions in for each customer which charges them for their services individually. I would like to generate a query that pulls all transactions and costs for related equipment and services. When I tried to join cus->billing->service->billing->equip it causes some weirdness. Does anyone know a better way to do this?
Select * from Customer as c
inner join Billing as b on c.customerID=b.customerID
inner join Service as s on b.ServID=s.ServID
inner join Billing on s.ServID=b.ServID
inner join Equipment as e on b.EquID=e.EquID AND b.Serial=e.Serial
where c.customerID=1

Although you have joined Billing table twice , you haven't used the second one. I think you can remove following from the query.
inner join Billing on s.ServID=b.ServID --(4th line of the query)

I got it working with some help from friends and the comments. Final code is below.
Select * from Customer as c
inner join Billing as b on c.customerID=b.customerID
left join Service as s on b.ServID=s.ServID
left join Equipment as e on b.EquID=e.EquID AND b.Serial=e.Serial
where c.customerID=1

Related

2 Tables - one customer, one transactions. How to handle a customer with no transaction?

I have 2 tables-one customers, one transactions. One customer does not have any transactions. How do I handle that? As I'm trying to join my tables, the customer with no transaction does not show up as shown in code below.
SELECT Orders.Customer_Id, Customers.AcctOpenDate, Customers.CustomerFirstName, Customers.CustomerLastName, Orders.TxnDate, Orders.Amount
FROM Orders
INNER JOIN Customers ON Orders.Customer_Id=Customers.Customer_Id;
I need to be able to account for the customer with no transaction such as querying for least transaction amount.
Use below updated query - Right Outer join is used instead of Inner join to show all customers regardless of the customer placed an order yet.
SELECT Orders.Customer_Id, Customers.AcctOpenDate,
Customers.CustomerFirstName, Customers.CustomerLastName,
Orders.TxnDate, Orders.Amount
FROM Orders
Right Outer JOIN Customers ON Orders.Customer_Id=Customers.Customer_Id;
INNER Joins show only those records that are present in BOTH tables
OUTER joins gets SQL to list all the records present in the designated table and shows NULLs for the fields in the other table that are not present
LEFT OUTER JOIN (the first table)
RIGHT OUTER JOIN (the second table)
FULL OUTER JOIN (all records for both tables)
Get up to speed on the join types and how to handle NULLS and that is 90% of writing SQL script.
Below is the same query with a left join and using ISNULL to turn the amount column into 0 if it has no records present
SELECT Orders.Customer_Id, Customers.AcctOpenDate, Customers.CustomerFirstName, Customers.CustomerLastName
, Orders.TxnDate, ISNULL(Orders.Amount,0)
FROM Customers
LEFT OUTER JOIN Orders ON Orders.Customer_Id=Customers.Customer_Id;
try this :
SELECT Orders.Customer_Id, Customers.AcctOpenDate, Customers.CustomerFirstName, Customers.CustomerLastName, Orders.TxnDate, Orders.Amount
FROM Orders
Right OUTER JOIN Customers ON Orders.Customer_Id=Customers.Customer_Id;
I strongly recommend LEFT JOIN. This keeps all rows in the first table, along with matching columns in the second. If there are no matching rows, these columns are NULL:
SELECT c.Customer_Id, c.AcctOpenDate, c.CustomerFirstName, c.CustomerLastName,
o.TxnDate, o.Amount
FROM Customers c LEFT JOIN
Orders o
ON o.Customer_Id = c.Customer_Id;
Although you could use RIGHT JOIN, I never use RIGHT JOINs, because I find them much harder to follow. The logic of "keep all rows in the first table I read" is relatively simple. The logic of "I don't know which rows I'm keeping until I read the last table" is harder to follow.
Also note that I included table aliases and change the CustomerId to come from customers -- the table where you are keeping all rows.
Using CASE will replace "null" with 0 then you can sum the values. This will count customers with no transactions.
SELECT c.Name,
SUM(CASE WHEN t.ID IS NULL THEN 0 ELSE 1 END) as TransactionsPerCustomer
FROM Customers c
LEFT JOIN Transactions t
ON c.Name = t.customerID
group by c.Name
SELECT c.Name,
SUM(CASE WHEN t.ID IS NULL THEN 0 ELSE 1 END) as numberoftransaction
FROM customers c
LEFT JOIN transactions t
ON c.Name = t.customerID
group by c.Name

Joining 3 tables in sql-server

I have three tables in sql-server like table A table B table C.
How can I join 3 tables as expressed in the image below?
More information needed to give you a correct piece of code, but from the image you need LEFT JOINs.
(ID's have been presumed)
SELECT *
FROM Customers c
LEFT JOIN Items i ON c.iid = i.id
LEFT JOIN Sales s ON c.sid = s.id
It's never too late :)
Most probably you'll need this:
select ...
from customers
full outer join (items inner join sales on (xxx)) on (xxx)

Suggestion needed for this Hive Query

I have a select statement with 5 ID columns. I need to lookup and select the corresponding customer names from a Customer master table that stores Ids/names and come up with a Customer report. The tables columns are as below:
origCustomerID,Tier1PartnerID,Tier2PartnerID,DistributorId,EndCustomerID,productId,OrderTotal,OrderDate
The first 5 columns are ID columns that match CustID column in the Customers table. Note that NOT all of these columns will contain a value for a given record at all times, i.e. they could be null at times. Given the current constraints in hiveQL, I can only think of the following way, but this takes up a lot of time and is not the best possible way. Could you please suggest any improvements to this?
Select origCustomerID,a.name,Tier1PartnerID,b.name,Tier2PartnerID,
c.name,DistributorId,d.name,EndCustomerID,e.name,productId,OrderTotal,OrderDate
From Orders O
LEFT OUTER JOIN customers a on o.origCustomerID = a.custid
LEFT OUTER JOIN customers b on o.Tier1PartnerID = a.custid
LEFT OUTER JOIN customers c on o.Tier2PartnerID = a.custid
LEFT OUTER JOIN customers d on o.DistributorId = a.custid
LEFT OUTER JOIN customers e on o.EndCustomerID = a.custid
If the id values are always either customer ids or NULL (i.e. in the case they are not NULL you are sure they are customer ids and not something else) and each record in the Orders table matches at most one customer (i.e. every record has at most one id in those five columns; or possible the same id several times), you could perhaps use COALESCE in your matching expression.
I can't test this at the moment, but this should join the records using the first non-NULL id from the Orders table.
SELECT [stuff]
FROM Orders O
LEFT OUTER JOIN customers a
ON COALESCE(o.origCustomerID,
o.Tier1PartnerID,
o.Tier2PartnerID,
o.DistributorId,
o.EndCustomerID) = a.custid
Hope that helps.

Filtering query with join statement

I am using ColdFusion 8 to develop my company's website and would like to return a list of records (just the clientname field) from a table (dbo.clients) that has no match in a different table (dbo.fees) for the purpose of prompting the end-user to add a fee schedule for those companies. An example:
dbo.clients
CLIENT_ID CLIENT_NAME
1 Joe's Diner
2 Save-a-Lot
3 Family Meds
4 DiFazio's
dbo.fees
CID CLIENT_NAME FEE
1 Joe's Diner 25.000
2 Save-a-Lot 35.000
4 DiFazio's 30.000
What I desire is a resultset that, in the case of the above tables/data, would return only clientid/clientname 3/Family Meds because they do not have a fee listed/record in the table dbo.fees. My DB is MSSQL 2005. My query is:
SELECT clientid
FROM clients
INNER JOIN fees
ON clients.clientid <> fees.cid;
Which returns a Cartesian product of 50,000+ results. Using LEFT/RIGHT OUTER JOIN still gives me a Cartesian product and DISTINCT simply returns every record from dbo.clients regardless of whether or not they have a dbo.fees entry or not. What am I doing wrong?
p.s. Also of note: The admin before me apparently did not set up a PK/FK relationship between the clients/fees tables and so any query syntax that might be reliant on that may not work in this situation. It would probably have to work based solely on the values of the relevant fields.
You can use a LEFT JOIN with a WHERE clause that will return only those records that do not appear in the fees table:
select c.CLIENT_ID, c.CLIENT_NAME
from clients c
left join fees f
on c.CLIENT_ID = f.CLIENT_ID
where f.CLIENT_ID is null
If you need help learning JOIN syntax, here is a great reference:
A Visual Explanation of SQL Joins
This can also be written using a NOT EXISTS:
select *
from clients c
where not exists (select CLIENT_ID
from fees f
where c.CLIENT_ID = f.CLIENT_ID)
See SQL Fiddle Demo with both queries
Simplest, you could just use a NOT IN;
SELECT clientid FROM clients WHERE clientid NOT IN
(SELECT clientid FROM fees)
...or you can use a LEFT JOIN to do the same thing a bit more verbosely; f.clientid will be NULL if a fee does not exist for the client.
SELECT c.clientid
FROM clients c
LEFT JOIN fees f
ON c.clientid = f.clientid
WHERE f.clientid IS NULL

What are some good examples where SQL's OUTER JOIN is used?

I often get asked the questions in an interview that "what is an outer join in SQL"?
While it can be answered, I wonder what might be some classic and good real life examples where a (LEFT) OUTER JOIN is used?
In the Northwind database on the Customers and Orders table.
Doing an inner join will only give you customers that have placed orders.
Doing an outer join will get all customers and orders for customers that have placed orders.
To add to Robin Day's answer, you can also use a Left Outer Join to grab only customers who have NOT placed orders by checking for NULL.
SELECT *
FROM Customer
LEFT OUTER JOIN Order
ON Customer.CustomerId = Order.CustomerId
WHERE Order.CustomerId IS NULL
Following is the visual represntation of the left outer join
SELECT <select_list>
FROM Table_A A
LEFT JOIN Table_B B
ON A.Key = B.Key
read more about joins in the below article
http://www.codeproject.com/KB/database/Visual_SQL_Joins.aspx ( one of the best article must read )
A LEFT OUTER JOIN can be used when you want all records from one table, as well as records from another table if any.
E.g., given table User and Address, where Address has a FK to User and there could be 0 or more addresses per user:
select *
from User u
left outer join Address a on u.UserID = a.UserID
This will ensure you get all User records, regardless of whether there was a corresponding Address record or not.
If you want to show all Users that do not have addresses, you can do this:
select *
from User u
left outer join Address a on u.UserID = a.UserID
where a.UserID is null
Classic example is cutomers and orders. Some customers have orders and others do not. You want to show a list of customers with total sales. So you do a left outer join from the customer to the order and get:
Customer A: $100;
Customer B: $0;
Customer C: $500
instead of:
Customer A: $100;
Customer C: $500
Here is an example:
I need a list of all customers, with their vouchers, I also need the customers that never used vouchers.
SELECT *
FROM Customer
LEFT OUTER JOIN Voucher
ON Customer.CustomerId = Voucher.CustomerId
Get a list of all customers including any details of orders they have made. Some customers may not have made orders and therefore an INNER JOIN would exclude them from this list.
SELECT
*
FROM
Customer
LEFT OUTER JOIN
Order
ON
Customer.CustomerId = Order.CustomerId