SQL joins over more than two tables - sql

I have 4 tables:
sales
products
vender_info
venders
Question is: display list of product_id whose vender and customer is different.
Please solve this question.
tables

Not sure what would you do with this data, but this is the query:
SELECT vp.PRODUCT_ID, vv.VENDERS, vs.CUSTOMERNAME
FROM vna_sales vs
JOIN vna_products vp ON vs.ORDERID = vp.ORDERID
JOIN vna_venders vv ON vp.VENDER_ID = vv.VENDER_ID
WHERE vv.VENDERS <> vs.CUSTOMERNAME

Please try this
SELECT *
FROM vna_shipments a
inner join vna_parts b on a.id = b.id //some joing factor
inner vna_suppliers c on a.id = c.id //some joing factor
inner vna_projects d on a.id = d.id //some joing factor
group by vendor_id, customer_id
order by vendor_id desc

Related

SQL query showing incorrect results

I am using Microsoft Access and I have this SQL query which does all the relevant joins:
SELECT c.ID
FROM ((((((((Cars c
INNER JOIN Offers
ON c.ID = Offers.car_id)
INNER JOIN Users u
ON c.owner_id = u.ID)
INNER JOIN City
ON u.city_id = City.ID)
INNER JOIN Models
ON c.model_id = Models.ID)
INNER JOIN Makes
ON Models.make_id = Makes.ID)
INNER JOIN Type
ON Models.type_id = Type.ID) ))
WHERE ( Offers.decision <> 3 )
In my Cars table I have 1 car and in my offers table I have 3 offers for the same car which have a Offers.decision of 2 and 4, for some reason when I execute the query it shows the same car 3 times like it is going on the basis of 3 offers.
Is their a way to show cars that do not have an Offers.decision of 3?
You should not use a join but a subquery:
SELECT * FROM Cars WHERE ID NOT IN (SELECT DISTINCT car_id FROM Offers WHERE decision <> 3)
Simplify your query to just:
SELECT c.ID
FROM Cars c INNER JOIN
Offers ON c.ID = Offers.car_id
WHERE (Offers.decision <> 3)

Join/Subquery is fast/slow depending on which column I filter on (not a simple index issue)

PostgreSQL 9.3.2, compiled by Visual C++ build 1600, 64-bit
Each customer can have many orders and referrals. Now, I want to create a view with some statistics for customer where, for each customer, I have some calculated columns (one row for each customer).
Create the view:
create view myview
select
a.customer_id,
sum(a.num) as num_orders,
sum(b.num) as num_referrals
from
(
select
customer.id as customer_id,
count(customer.id) as num
from
customer
left join
order
on
order.customer_id = customer.id
group by
customer.id
) a
left join
(
select
customer.id as customer_id,
count(customer.id) as num
from
customer
left join
referral
on
referral.customer_id = customer.id
group by
customer.id
) b
on
a.customer_id = b.customer_id
group by
a.customer_id,
b.customer_id
;
Query A (this is fast):
select
customer.*,
myview.*
from
customer
left join
myview
on
customer.id = myview.customer_id
where
customer.id = 100
;
Query B (this is SLOW):
select
customer.*,
myview.*
from
customer
left join
myview
on
customer.id = myview.customer_id
where
customer.sex = 'M'
;
Query C (this is fast):
select
customer.*,
myview.*
from
customer
left join
myview
on
customer.id = myview.customer_id
where
(select id from customer where sex = 'M')
;
OK, so why is Query B so much different than Query A in terms of performance? I guess, in Query B, it is running those subqueries first without filtering, but I don't know how to fix it.
The problem is that it is our ORM that is generating the query. So, I can't fix the problem by doing something like Query C.
I'm hoping there's just a better way to design my view to fix the problem. The main difference in the EXPLAIN results between Query A and Query B is that Query B has some MERGE RIGHT JOIN operations.
Any ideas?
EDIT:
I added following information per requests from people commenting. The following is the more true-to-life info (as opposed to the simplified, hypothetical scenario above).
create or replace view myview as
select
a.id_worder,
count(a.*) as num_finance_allocations,
count(b.*) as num_task_allocations
from
(
select
woi.id_worder,
count(*) as num
from
worder_invoice woi
left join
worder_finance_task ct
on
ct.id_worder_finance = woi.id
left join
worder_finance_task_allocation cta
on
cta.id_worder_finance_task = ct.id
group by
woi.id_worder
) a
left join
(
select
wot.id_worder,
count(*) as num
from
worder_task wot
left join
worder_task_allocation wota
on
wota.id_worder_task = wot.id
group by
wot.id_worder
) b
on
a.id_worder = b.id_worder
group by
a.id_worder,
b.id_worder
;
Query A (fast, apparently I need a rep of more than 10 to post more than 2 links, so no EXPLAIN for this one)
select
*
from
worder a
left outer join
myview b
on
a.id = b.id_worder
where
a.id = 100
;
Query B (SLOW, EXPLAIN)
select
*
from
worder a
left outer join
myview b
on
a.id = b.id_worder
where
a.id_customer = 200
Query C (fast, EXPLAIN)
select
*
from
worder a
left outer join
myview b
on
a.id = b.id_worder
where
a.id = (select id from worder where id_customer = 200)
;
Try rewriting your view like so:
create view myview
select
c.customer_id,
(
select count(*) from order o where o.customer_id=c.customer_id
) num_orders,
(
select count(*) from referral r where r.customer_id=c.customer_id
)
from customer c ;

SQL Query or Table Error?

So Im trying to find the total amount spent on Cuts and Products by each Customer
I don't know if my Query is Wrong or my entire Database Schema any ideas?
My Query
`Select First_Name, SUM(B.Cost), SUM(C.Cost)
FROM bookings A, cuts B, products C, customers D
Where A.Customer_ID= D.Customer_ID
AND A.Cut_ID = B.Cut_ID
AND A.Product_ID= C.Product_ID;`
My Database
`Table: bookings
Booking_N0, Customer_ID, Cut_ID, Product_ID, TimeTaken`
`Table: customers
Customre_ID, First_Name, Sex`
`Table: products
Product_ID, Products, Cost`
`Table: cuts
Cut_ID, Cut, Cost`
You should GROUP BY to SUM by each customer :
Select D.First_Name
, SUM(B.Cost)
, SUM(C.Cost)
FROM bookings A LEFT JOIN cuts B ON A.Cut_ID = B.Cut_ID
JOIN products C ON A.Product_ID = C.Product_ID
JOIN customers D ON A.Customer_ID = D.Customer_ID
GROUP BY D.First_Name;
Also, look forward using explicit join notation (FROM table1 t1 JOIN table2 t2 ON t1.field1 = t2.field2) instead of implicit join notation (FROM table1 t1, table2 t2 WHERE t1.field1 = t2.field2), because it is has more intuitive view (tables are listed near conditions on which they are joined).
Start using recommended JOIN / ON syntax for joining instead of using WHERE clause . You also need a GROUP BY clause
Select First_Name, SUM(B.Cost), SUM(C.Cost)
FROM bookings A
INNER JOIN cuts B
ON A.Cut_ID = B.Cut_ID
INNER JOIN products C
ON A.Product_ID= C.Product_ID
INNER JOIN customers D
ON A.Customer_ID= D.Customer_ID
GROUP BY First_Name
If you use aggregate function like SUM you have to add a group by clause
in your case:
...
AND A.Product_ID= C.Product_ID
GROUP BY First_Name

JOIN syntax in MS ACCESS

I was tasked to create a new report on a legacy program. I needed to LEFT JOIN a table but I am getting Syntax error on JOIN Operation.
My SQL query as follows:
SELECT
SUM(b.qty) as qty,
b.price,
c.item_desc,
a.cust_name,
e.curr_symbol
FROM (
tran_hdr a,
tran_dtl b,
items c ,
tailoring e
(
LEFT JOIN
customers d
ON a.cust_name = d.name
)
)
WHERE a.tran_id = b.tran_id
AND b.item_no = c.item_no
GROUP BY b.price,
c.item_desc,
a.cust_name,
e.curr_symbol
I am joining the tran_hdr to customers. Because not all customers in Tran Header is maintained in customer table, but report requirest to show all Data in Transaction table.
You're messing up your JOINs.
And your Tailoring table has no relation whatsoever to other table.
So, just try this one out:
SELECT
b.price,
c.item_desc,
a.cust_name,
e.curr_symbol,
SUM(b.qty) as qty
FROM
tran_hdr a
INNER JOIN tran_dtl b
ON a.tran_id = b.tran_id
INNER JOIN items c
ON b.item_no = c.item_no
LEFT JOIN
customers d
ON a.cust_name = d.name
,tailoring e
GROUP BY b.price,
c.item_desc,
a.cust_name,
e.curr_symbol

Get one to many relation data

Hi everyone I am having three tables.
Customer(list of customers)
Payments(list of customer payment)
Orders(list of customer orders)
customer can have more than one payment and order that is one to many relation.
I tried following query but it is not showing proper result.
select a.name, b.job_date as JobDate, c.order_date as OrderDate from Customers a
inner join Jobs b on a.id = b.customer_id
inner join Orders c on a.id = c.customer_id
where a.id = 1;
What i need is to show a customer's orders and jobs.
Try left join instead of inner join. child tables might not have records assosiated with Customers.id =1.
select a.name, b.job_date as JobDate, c.order_date as OrderDate from Customers a
left join Jobs b on a.id = b.customer_id
left join Orders c on a.id = c.customer_id
where a.id = 1;
If you want to get all the orders you can use the following :
select a.name, c.order_date as OrderDate from Orders c
inner join Customers a on a.id = c.customer_id
where a.id = 1;
You get build a similar query to get all the employee's jobs:
select a.name, b.job_date as JobDate from Jobs b
inner join Customers a on a.id = b.customer_id
where a.id = 1;