I wrote a program about finding products sold in both France and Germany. On the other hand, I'm not happy with my subqueries. I have a feeling that all the joins could be skipped and done much faster, yet I could not find an answer to this problem.
Here is the code:
select productname
from products p
join [Order Details] od on p.productid = od.ProductID
join orders o on od.OrderID = o.OrderID
join customers c on o.CustomerID = c.CustomerID
where p.ProductID in (select p.productid
from products p
join [Order Details] od on p.productid = od.ProductID
join orders o on od.OrderID = o.OrderID
join customers c on o.CustomerID = c.CustomerID
where c.Country LIKE 'France')
and p.ProductID in (select p.productid
from products p
join [Order Details] od on p.productid = od.ProductID
join orders o on od.OrderID = o.OrderID
join customers c on o.CustomerID = c.CustomerID
where c.Country LIKE 'Germany')
group by productname
So what I'm asking for is to maybe simplify this as much as possible but in basic ways, or show the way to skip that joins etc.
https://i.stack.imgur.com/UWlzn.png
select productname
from products p
join [Order Details] od on p.productid=od.ProductID
join orders o on od.OrderID=o.OrderID
join customers c on o.CustomerID=c.CustomerID
where c.Country in ('France', 'Germany')
group by productname
having COUNT(DISTINCT c.Country) = 2;
Related
SQL Practice from W3Schools
SELECT C.country,
Round(Sum(P.price * OD.quantity), 2) AS Revenue
FROM [orders] AS O
INNER JOIN [orderdetails] AS OD
ON O.orderid = OD.orderid
INNER JOIN [products] AS P
ON OD.productid = P.productid
INNER JOIN [customers] AS C
ON O.customerid = C.customerid
WHERE C.country = (SELECT C.country
FROM [orders] AS O
INNER JOIN [orderdetails] AS OD
ON O.orderid = OD.orderid
INNER JOIN [products] AS P
ON OD.productid = P.productid
INNER JOIN [customers] AS C
ON O.customerid = C.customerid
GROUP BY C.customerid
ORDER BY Round(Sum(P.price * OD.quantity), 2) DESC
LIMIT 1)
My joins are duplicated from main to sub-query.
Is there anyway to reduce code replication in this query?
This should be easy for you, but I'm lost here:
I have a database with 4 tables: orders, clients, products, orders_products
I need to fetch all clients, with all of their orders, including the ones that don't have any order.
I'm only getting the ones that have made an order. Poor old "Nick" in the Clients table won't show up.
What am I doing wrong here?
SELECT c.name clientname, o.id orderID, GROUP_CONCAT(p.name) productNAMEs,
GROUP_CONCAT(p.id) productIDs
FROM clients c, orders o, orders_products op, products p
WHERE c.id = o.client_id
AND c.status = 1
AND o.id = op.order_id
AND p.id = op.product_id
GROUP BY c.name
See table definitions here:
https://www.db-fiddle.com/f/bTRSLfYTa19S2EpE2zKwUv/7
Update
#scaisedge came up with an answer that includes clients without orders:
SELECT c.name clientname, o.id orderID, GROUP_CONCAT(p.name) productNAMEs,
GROUP_CONCAT(p.id) productIDs
FROM clients c
LEFT JOIN orders o ON c.id = o.client_id
LEFT JOIN orders_products op ON o.id = op.order_id
LEFT JOIN products p ON p.id = op.product_id
WHERE c.status = 1
GROUP BY c.name
You can see the results here: https://www.db-fiddle.com/f/8bGcQJSbSFmKMUo1tLuZuA/1
It seems that not using JOINs was my problem.
Use explicit join sintax and left join for retrive also row that don't match
SELECT c.name clientname, o.id orderID, GROUP_CONCAT(p.name) productNAMEs,
GROUP_CONCAT(p.id) productIDs
FROM clients c
LEFT JOIN orders o ON c.id = o.client_id
LEFT JOIN orders_products op ON o.id = op.order_id
LEFT JOIN products p ON p.id = op.product_id
WHERE c.status = 1
GROUP BY c.name
I recommand you to use JOIN's to UNIFY the tables data. A JOIN clause is used to combine rows from two or more tables, based on a related column between them.
https://www.w3schools.com/sql/sql_join.asp
SELECT *
FROM clients LEFT JOIN orders ON clients.id = orders.client_id
LEFT JOIN orders_products ON clients.id = orders_products.order_id
LEFT JOIN products ON products.id = orders_products.product_id
WHERE clients.status = 1;
Never use commas in the FROM clause. Always use proper, explicit, standard JOIN syntax.
Also, your GROUP BY needs to match the unaggregated columns in the SELECT.
I'm not sure if you intend this:
SELECT c.name as clientname, o.id as orderID,
GROUP_CONCAT(p.name) as productNAMEs,
GROUP_CONCAT(p.id) productIDs
FROM clients c left join
orders o
on c.id = o.client_id left join
orders_products op
on o.id = op.order_id left join
products p
on p.id = op.product_id
WHERE c.status = 1
GROUP BY c.name, o.id;
Or:
SELECT c.name as clientname,
GROUP_CONCAT(p.name) as productNAMEs,
GROUP_CONCAT(p.id) productIDs
FROM clients c left join
orders o
on c.id = o.client_id left join
orders_products op
on o.id = op.order_id left join
products p
on p.id = op.product_id
WHERE c.status = 1
GROUP BY c.name;
I need to select the customer and product code and the date on which the order was made, but I'm having some trouble with the join orders.
My SQL select:
select c.customerNumber, p.productCode, o.orderDate as data_compra
from customers as c inner join orders as o
inner join products as p
where p.productCode =
any (
select p2.productCode from products as p2
inner join orders as o
inner join orderdetails as odt
where o.orderNumber = odt.orderNumber and
p2.productCode = odt.productCode
)
and o.orderNumber =
any (
select o2.orderNumber from orders as o2
inner join orderdetails as odt
where o.orderNumber = odt.orderNumber and
p.productCode = odt.productCode
)
Two simple joins should do what you want:
select
c.customerNumber,
d.productCode,
o.orderDate
from customer c
join orders o on o.customerNumber = c.customerNumber
join orderdetails d on d.orderNumber = o.orderNumber
In the code you're asking to inner join two tables but not specifying the relationship. You need to do so SQL can relate and match the rows in each table.
You do this with the ON keyword.
I suggest you watch this video and read this article before continuing
I hope that you can help me with this slightly thorny problem. I am using the W3Schools SQL tutorial and in the process of doing this, I am inventing 'real-world' queries to try and get some experience at this stuff. Using their database, I am trying to find out who ordered what using the following:
SELECT c.CustomerName, p.ProductName
FROM Customers c inner join Orders o on c.CustomerID = o.CustomerID
JOIN OrderDetails od on od.OrderID = o.OrderID
JOIN Products p on p.ProductID = od.ProductID;
This keeps returning the error:
Syntax error (missing operator) in query expression 'c.customerid = o.customerid join orderdetails od on od.orderid = o.orderid join products p on p.productid = od.productid'.
After lots of fiddling about, and having a more experienced colleague look at my query, we can't find what's wrong with what I have written.
Please could you provide me with some help/guidance.
this query is not wrong and not giving any error i'm ruining this query on w3school http://www.w3schools.com/sql/trysql.asp?filename=trysql_select_all
open this link and paste the query.
SELECT c.CustomerName, p.ProductName
FROM Customers c inner join Orders o on c.CustomerID = o.CustomerID
JOIN OrderDetails od on od.OrderID = o.OrderID
JOIN Products p on p.ProductID = od.ProductID;
Refer to their documentation here - https://www.w3schools.com/sql/sql_join_inner.asp
Section - "JOIN Three Tables"
If I re-write your code like below then it works fine in W3School's try it editor.
SELECT c.CustomerName, p.ProductName
FROM ( ( ( Customers c inner join Orders o on c.CustomerID = o.CustomerID )
inner JOIN OrderDetails od on od.OrderID = o.OrderID )
inner JOIN Products p on p.ProductID = od.ProductID );
I have added a variable in SSIS and I am trying to add tha variable in my expression query. But it says Expression cannot be evaluated Below is my expression query. Please help if you know where I am making mistakes.
SQL Query
SELECT c.CustomerName, o.OrderID from Customers c
INNER JOIN Orders o ON c.CustomerID=o.CustomerID
Inner Join OrderDetails od ON od.OrderId = o.OrderID
Inner Join Products p on p.ProductID = od.ProductID
where ISNULL(c.IsResult,0) = 0 and o.CompanyID = #CompanyID
Expression Format
"SELECT c.CustomerName, o.OrderID from Customers c
INNER JOIN Orders o ON c.CustomerID=o.CustomerID
Inner Join OrderDetails od ON od.OrderId = o.OrderID
Inner Join Products p on p.ProductID = od.ProductID
where ISNULL(c.IsResult,0) = 0 and o.CompanyID ="+ #[User::intCompanyID]
Let me know if I am doing it right.
I found that casting the numeric values to String or Unicode works. so maybe try
ISNULL(c.IsResult,0) = 0 and o.CompanyID ="+ (DT_WSTR,20) #[User::intCompanyID]
Have you tried the following
"SELECT c.CustomerName, o.OrderID from Customers c
INNER JOIN Orders o ON c.CustomerID=o.CustomerID
Inner Join OrderDetails od ON od.OrderId = o.OrderID
Inner Join Products p on p.ProductID = od.ProductID
where ISNULL(c.IsResult,0) = 0 and o.CompanyID = ?"
NOTE: The image is from a different example
Click on the "Parameters" button and you can then selected your parameter from there.
Hope this helps.