I am trying out SQL and having trouble figuring out making queries when it comes to combining info from multi tables. Been using w3school but they don't seem to have similar reference to the question below. Was thinking of joining them as my codes below but still that doesn't answer the question. Appreciate any advice. Thanks.
Question:
Products(itemID, description, quantity, supplierID)
Supplier(supplierID, name, address)
A product can be supplied by more than one supplier. Write the SQL to
list the quantity of each product by each supplier.
SELECT Products.quanity, Supplier.name
FROM Products INNER JOIN Supplier
ON Products.supplierID = Supplier.supplierID;
Assuming that the product table does not have two rows for the same supplier and product, then your query is very close. I would write it as:
SELECT p.description as ProductDescription, s.name as SupllierName, p.Quantity
FROM Products p INNER JOIN
Supplier s
ON p.supplierID = s.supplierID
ORDER BY p.description, p.Quantity desc;
Note the following:
The use of tables aliases (the p and s) make the query more readable and are used for every column reference.
The final result is explicitly order by product, with the largest quantity first.
If there are multiple rows for a given product and supplier, then you will need aggregation.
Looks like you need to use group by here:
select itemId, supplierId, sum(quantity) from Products group by itemId, supplierId;
Related
I'm trying to merge these two statements into one query to get the a list of product names(or ids) against the average of their TTFF data, and I'm stuck.
select AVG(TTFF) from TTFFdata group by product_id
select product.product_name, count(*) from product join TTFFdata on product.product_id = TTFFdata.product_id
I've looked into using a temporary table (CREATE TEMPORARY TABLE IF NOT EXISTS averages AS (select AVG(TTFF) from TTFFdata group by product_id)) but couldn't get that to work with a join.
Anyone able to help me please?
You need to understand the components. Your second query is missing a group by. This would seem to be what you want:
select p.product_name, count(t.product_id), avg(t.TTFF)
from product p left join
TTFFdata t
on p.product_id = t.product_id
group by p.product_name
It is better to do group by on product_id, product_name for two reasons. One is, you can select product id along with product name. Second reason is, If the product name is not unique then it may give wrong results(this may be a rare scenario like product name is same but it differs based on other columns like version or model). The below is the final query.
select Product.product_id,
product_name,
AVG(TTFF) as Avg_TTFF
from Product
inner join
TTFFdata
on Product.product_id = TTFFdata.product_id
group by Product.product_id,Product.product_name
TTFFdata:
product:
Output:
I was reading some tutorials about group by clause, i faced the following problem and don't know why it was solved like that, the table is as follows:
the requirement is to select the most expensive product in each category, and the following query was the answer:
SELECT
categoryID, productID, productName, MAX(unitprice)
FROM
products A
WHERE
unitprice = (
SELECT
MAX(unitprice)
FROM
products B
WHERE
B.categoryId = A.categoryID)
GROUP BY categoryID;
i don't know why the above query was the answer, why it wasn't just:
SELECT
categoryID, productID, productName, MAX(unitprice)
FROM
products
GROUP BY categoryID;
also, if the first query is the right one, why MAX function exists in the outer and inner query, isn't it enough to exist in the inner query?
thanks.
The second query will produce an error because it is not possible to have columns in the select clause whitout grouping by them in the Group by clause (unless they are subject to the aggregation).
Therefore you need to first find the highest unit price in each category and then find which product has that uniprice. You can actually accomplish this in many ways. This first query is one of them.
From your picture it looks as others have mentioned that you are using mysql, the MYSQL optimiser doesn't like subqueries very much and it would horrible to run over lots of data, best habit is to use joins where possible (if you look at query plans in postgres, oracle or mssql it will re-write sub-queries as joins 90% of the time)
The second query will run on default mysql as it will group by the missed columns you missed.
Below is an example:
SELECT
A.categoryID, A.productID, A.productName, B.max_unitprice
FROM products A
JOIN (
SELECT
max(unit price) as max_unitprice,
categoryId
FROM products
GROUP BY categoryId) B
ON B.categoryId = A.categoryID
SELECT p.*
FROM products p
WHERE NOT EXISTS ( SELECT 'p2'
FROM products p2
WHERE p2.categoryId = p.categoryId
AND p2.unitPrice > p.unitPrice
)
I have 3 tables: products, orders and orderLines(order_id, product_id).
I have an sql query to figure out which seems nearly impossible to do in only one query.
Is there a way to have in only one query:
All the products but showning a specific order's products first;
which means that: for an order A: show product1, product2.. present in orderA's orderLines first, than the following products (not ordered) are shown next.
PS:
I know it's possible to achieve this with a union of two queries, but it would be better to have it done in only one query.
You can put a subquery in the order by clause. In this case, an exists subquery is what you need:
select p.*
from products p
order by (exists (select 1
from orderlines ol
where p.productid = ol.productid and o.orderid = ORDERA
)
) desc;
Pretty new to sql statements here so this one is a bit tricky for me.
I have two tables: sold and product. Sold(SID, UPC, Date) Product(UPC, Name, Brand)
I need to find in how many stores(sid) does one brand outsell another brand.
I was thinking it was something like:
select count(*) from sold natural join product
where count(brand = 'sony') > count(brand = 'samsung');
Clearly that isn't valid however...
SELECT COUNT(*)
FROM (
SELECT SID
FROM Sold
JOIN product
ON product.UPC = Sold.UPC -- otherwise we have a cartesian product
GROUP BY SID -- if we need totals _by store_, we need to group on that.
HAVING SUM(brand='sony') > SUM(brand='samsung')
) Totals.
I have the following query:
SELECT
DISTINCT sites.site_id,
sites.site_name,
sites.site_url,
earnings.cust_id
FROM
sites,
earnings
WHERE sites.site_id = earnings.site_id AND sites.site_id IN('8', '1666')
That query gives me very well the information asked. It returns two rows, one for site 8 and another for site 1666, with the information on them from those tables.
Now, I want that the cust_id number be used to select from another table (let's say table customers) where they are stored by id and where other info is such as name, last name, etc.
Basically what I need is to expand that query to extract customer name and last name from the table customers, using the ids obtained.
Same way you got the info from two tables. Add a comma, add the third table name, and add the relationship to your WHERE clause like you did with the first two tables.
SELECT
DISTINCT sites.site_id,
sites.site_name,
sites.site_url,
earnings.cust_id,
customers.name,
customers.last_name
FROM
sites,
earnings,
customers
WHERE sites.site_id = earnings.site_id AND sites.site_id IN('8', '1666') AND customers.id = earnings.cust_id
I think it's clearer to write out the JOINs though:
SELECT
sites.site_id,
sites.site_name,
sites.site_url,
earnings.cust_id,
customers.name,
customers.last_name
FROM
sites
INNER JOIN
earnings
ON
earnings.site_id = sites.site_id
INNER JOIN
customers
ON
customers.id = earnings.cust_id
WHERE
sites.site_id IN (8, 1666)
GROUP BY
sites.site_id