SQL update query with subquery search condition - sql

I have a homework question where we need to write an UPDATE statement to change category name of Categories in Ass7 by removing its last two characters if the category's products in dbo schema has an average unit price above $30.
Ass7 is a Schema we made of a database that has the relevant tables Categories and Products. the Categories table has the Category Name and the Products table has unit prices, with each product having a category ID. I was trying something like this
UPDATE Ass7.Categories
SET CategoryName = LEFT(CategoryName, (LEN(CategoryName) - 2))
WHERE EXISTS (
SELECT CategoryID
,AVG(UnitPrice) AS average
FROM Ass7.Categories
INNER JOIN dbo.Products ON Ass7.Categories.CategoryID = dbo.Products.CategoryID
WHERE average > 30
GROUP BY Ass7.Categories.CategoryID
);
But I'm a but confused as to where to go.

I think you are over-complicating the query. you just need a sub-query which return category_id of products having avg(unit_price) > 30 as below.
UPDATE Ass7.Categories
SET CategoryName = LEFT(CategoryName, (LEN(CategoryName) - 2))
WHERE CategoryID IN(
SELECT p.CategoryID
FROM dbo.Products p
GROUP BY p.CategoryID
having AVG(p.UnitPrice) > 30
);

Related

Returning complex query on update sql

I want to return query with multiple joins and with clause after updating something.
For example my query is:
WITH orders AS (
SELECT product_id, SUM(amount) AS orders
FROM orders_summary
GROUP BY product_id
)
SELECT p.id, p.name,
p.date_of_creation,
o.orders, s.id AS store_id,
s.name AS store_name
FROM products AS p
LEFT JOIN orders AS o
ON p.id = o.product_id
LEFT JOIN stores AS s
ON s.id = p.store_id
WHERE p.id = '1'
id
name
date
orders
store_id
store_name
1
pen
11/16/2022
10
1
jj
2
pencil
11/10/2022
30
2
ff
I want to return the exact query but with updated result in my update:
UPDATE products
SET name = 'ABC'
WHERE id = '1'
RETURNING up_qeury
Desired result on update:
id
name
date
orders
store_id
store_name
1
ABC
11/16/2022
10
1
jj
You can try UPDATE products ... RETURNING *. That may get you the content of the row you just updated.
As for UPDATE .... RETURNING someQuery, You Can't Do Thatâ„¢. You want to do both the update and a SELECT operation in one go. But that's not possible.
If you must be sure your SELECT works on the precisely the same data as you just UPDATEd, you can wrap your two queries in a BEGIN; / COMMIT; transaction. That prevents concurrent users from making changes between your UPDATE and SELECT.

Get suppliers that doesn't belong to a category in another table

I'm looking for a query where I need to show all the Suppliers from the Suppliers table that doesn't have products from category 1 (Products.CategoryID = 1). Whenever I run it it always gives an error.
Select SupplierID From Suppliers su
where SupplierID NOT IN
(select distinct SupplierID from Products
where SupplierID in
(select SupplierID from Products where CategoryID=1)
Side question: How do I get these results but with suppliers that has products from cat. 6 ? (So none from cat1 but does have from cat6).
Rather than using sub-selects, try to use set based operations like joins or exists. One option for your situation is below, though there are several ways to achieve what you are looking to do. Which one is best will depend on your data:
select su.SupplierID
From Suppliers as su
where not exists(select null -- The only check here is for a record, so you can select any value and it won't change the functionality
from Products as p
where su.SupplierID = p.SupplierID
and p.CategoryID = 1
)

SQL SELECT only the rows not containing ID used in related table

I have two tables with simple relation. One table is list of sales. The second table is list of products. Relation is that in the Sales table is a Product ID that points to the given product.
I need to retrieve the details on the products that were never sold.
Here are links to the two tables:
Table with Products & Table with Sales
If you don't want to click it, the tables look like this:
**SALES**
id
sale_id
product_id
quantity
**PRODUCTS**
id
name
category_id
stock
brand_id
price
color
warranty
So far I have this:
SELECT products.id
FROM products
LEFT JOIN sale_products ON sale_products.product_id = products.id
WHERE products.id NOT IN (sale_products.product_id)
GROUP BY products.id
But this doesn't retrieve anything, although if I take out the NOT then I get all the 17 IDs of the 17 sold items...
So I'd say it either has to be changed around or done with completely different approach..
Any help is much appreciated and welcome.
Try this:
SELECT products.id
FROM products
LEFT JOIN sale_products ON sale_products.product_id = products.id
WHERE sales_products.product_id IS NULL
GROUP BY products.id
You are asking for all products and for each product, either get a sales record or if no sales record found, return NULL for each column in the sales_product table.
SELECT
*
FROM
PRODUCTS P
WHERE
P.ID NOT IN (
SELECT
PRODUCT_ID
FROM
SALES
)

tricky sql query - finding alternative supplier( relational division )

This is a question I got from a book (don't remember which), it goes like this:
You have three tables:
Supplier (supId, name)
Product (prodId, name)
inventory (supId, prodId)
You need to find, with one query, all the suppliers that have in their inventory all the products (or more) supplier X has (lets say supplier X is the one with supId=1).
(so if supplier 1 has in his inventory bananas and apples, you need to find all the suppliers that carry at least bananas and apples)
You can use standard SQL only (including joins).
Apparently this is a known issue/question, you should check out this question:
How to filter SQL results in a has-many-through relation
(excellent solutions and analysis)
That problem is known as relational division.
One solution is double negation. You can select all suppliers, for whom no product delivered by supplier X exists, that is not delivered by them:
select distinct other_supplier.SupID
from Inventory other_supplier
where not exists
(
select *
from Inventory supplier_X
where supplier_X.supId = 1 -- For supplier X
and not exists
(
select *
from Inventory other_product
where other_supplier.supId = other_product.Supid
and supplier_X.prodId = other_product.prodId
)
)
Live example at SQL Fiddle.
I believe this solution uses standard SQL, except for the parameter definition.
DECLARE #supplierX int = 4
SELECT
[s].[supid],
[s].[name]
FROM [Inventory] [i1]
INNER JOIN [Inventory] [i2] ON [i1].[prodid] = [i2].[prodid]
INNER JOIN [Supplier] [s] ON [i1].[supid] = [s].[supid]
WHERE
[i1].[supid] <> #supplierX
AND [i2].[supid] = #supplierX
GROUP BY
[s].[supid],
[s].[name]
HAVING
COUNT(*) >= (SELECT COUNT(*) FROM [Inventory] [i3] WHERE [i3].[supid] = #supplierX)
A Fiddle is found here.
A breakdown of the query above:
Determine the number of products supplierX has in it's inventory (count(*))
Determine the products other suppliers share with supplierX (join by prodid)
Make sure the number of shared products is higher than or equal to the number of products supplierX has in it's inventory (HAVING COUNT() >= ...)

how do i use 'distinct' properly for my product query

I have a product catalog with
a product table (tblProducts : ProductID),
a product category table (tblProductCategories : CatID),
a product sub-category table (tblProductSubCategories : SubCatID), and
a xref table (tblProdXCat : ProductID,CatID,SubCatID)
that links the products to cats and subcats.
Products can be linked to multiple cats and/or subcats.
How can I query and get distinct products only (no product duplicated in result set)?
Microsoft SQL Server please.
Thanks!
I assume your tblProducts table is a table of distinct products, so you aren't asking how to select distinct products from thence.
If you mean how to get distinct products from tblProdXCat, then it's probably as simple as SELECT DISTINCT ProductID FROM tblProdXCat.
But maybe you want a complete information about the products rather than simply their IDs. In that case you could just INNER JOIN that list of distinct ProductID values against tblProducts:
SELECT p.*
FROM Products p
INNER JOIN (SELECT DISTINCT ProductID FROM tblProdXCat) x
ON p.ProductID = x.ProductID
If that is still not what you want then you may need to clarify your request.
select distinct productID from tblProducts
Put all the joining ambiguity into the WHERE clause.
SELECT *
FROM Products
WHERE ProductID in
(
SELECT ProductId
FROM Products JOIN ...
)