how could you rewrite this query doesn't use a sub query? - sql

Since a sub query returns rows and columns, you can join against a sub query just like you can join against a normal table.
SELECT
P.ProductCode, I.QuantityInStock as Qty, P.Title, P.Price
FROM
Products as P
JOIN
(SELECT * FROM Inventory) as I on (P.ProductCode = I.ProductCode);
How could you rewrite this query so it doesn't use a sub query?
am trying to rewrite but am not sure is correct
SELECT P.ProductCode, I.QuantityInStock as Qty, P.Title, P.Price
FROM Products as P
WHERE Inventory as I on (P.ProductCode = I.ProductCode);
Is this correct?

SELECT P.ProductCode, I.QuantityInStock as Qty, P.Title, P.Price
FROM Products as P
JOIN Inventory as I on P.ProductCode = I.ProductCode;

Since you're selecting ALL columns from Inventory you can just do
SELECT
P.ProductCode, I.QuantityInStock as Qty, P.Title, P.Price
FROM
Products as P
JOIN
Inventory I on P.ProductCode = I.ProductCode;

SELECT P.ProductCode, I.QuantityInStock as Qty, P.Title, P.Price
FROM Products as P, Inventory as I
WHERE P.ProductCode = I.ProductCode

Related

Query returning incorrect result

I wrote the below SQL query for pulling the revenue of a specific product Id (500) but it's returning 9335 results but all same (duplicates).
DECLARE #ProductID char(3) = '500'
SELECT
P.ProductID,
P.Name,
P.Price,
S.Quantity,
CAST(Price * Quantity AS float) AS Revenue
FROM
Sales S
INNER JOIN
Products P ON S.ProductID = P.ProductID
WHERE
p.ProductID = #ProductID;
Presumably, you want aggregation:
SELECT P.ProductID, P.Name, P.Price,
SUM(Price*Quantity) as Revenue
FROM Sales S INNER JOIN
Products P
ON S.ProductID = P.ProductID
WHERE p.ProductID = #ProductID
GROUP BY P.ProductID, P.Name, P.Price;

SQL Query to get highest values based on one column by grouping on another column

I am running the following SQL query to select the highest priced product in each product category in https://www.w3schools.com/sql/trysql.asp
SELECT p.ProductID, p.productName, p.Price, p.CategoryID, c.CategoryName
FROM [Categories] c
LEFT JOIN [Products] p
ON (c.CategoryID = p.CategoryID)
WHERE Price IN (SELECT Max(Price) FROM Products GROUP BY CategoryID)
ORDER BY p.CategoryID
However, the output that is generated is giving 2 results for some categories like category 3 and 4. Why is that happening? and how can I modify the code to get only highest result for each? Also, how do I get lowest for each category?
use row_number()
slect a.* from (SELECT p.ProductID, p.productName, p.Price, p.CategoryID, c.CategoryName,
row_number()over(partition by p.CategoryID order by p.Price desc) rn
FROM [Categories] c
LEFT JOIN [Products] p
ON c.CategoryID = p.CategoryID
) a where a.rn=1
APPLY comes to mind as perhaps the simplest approach:
SELECT p.ProductID, p.productName, p.Price, p.CategoryID, c.CategoryName
FROM categories c OUTER APPLY
(SELECT TOP (1) p.*
FROM Products p
WHERE p.CategoryID = c.CategoryID
ORDER BY p.Price DESC
) p
ORDER BY c.CategoryID

Hi i have some problems with a T-SQL using *

Group the ProductID orders, get a total by ProductID, the total of the orders and what represents the ProductID orders of the total order (that is a percentage). Columns Required: PercenofTotal (UnitPrice * Quantity), TotalAmount (UnitPrice * Quantity), PercentofTheTotal (UnitPrice * Quantity)
So this is my code, what i dont know is to do the percentofTheTotal and TotalAmount
SELECT P.ProductID, (P.UnitPrice * ODQuantity) AS tOTALaMOUNTByProductID, (P.UnitPrice * Quantity) as TotalAmount , (P.UnitPrice * OD.Quantity) as PercenofTotal
From Products as P,
From OrderDetails as OD
Group by P.ProductID
you're trying to do something complicated with simple statements that are not correct. Something like this could possibly do what you want to achieve.
USE AdventureWorks2014
GO
SELECT P.ProductID
, SUM(P.StandardCost * OD.OrderQty) AS TotalAmountByProductID
, MAX(SumTA.TotalAmount) AS TotalAmount
, (SUM(P.StandardCost * OD.OrderQty) / (MAX(SumTA.TotalAmount))*100) AS PercentOfTotal
FROM Production.Product as P
INNER JOIN Sales.SalesOrderDetail as OD on P.ProductID = OD.ProductID
LEFT OUTER JOIN (
SELECT max(pid) as pid, SUM(TA.TotalAmount) as TotalAmount
FROM
( SELECT '1' as pid, P.ProductID, SUM(P.StandardCost * OD.OrderQty) AS TotalAmount
FROM Production.Product as P
JOIN Sales.SalesOrderDetail as OD on P.ProductID = OD.ProductID
Group by P.ProductID
)AS TA
) AS SumTA ON SumTA.pid = '1'
Group by P.ProductID
ORDER BY PercentOfTotal Desc

Could not get the expected query with SQL Server

I´m trying to do a SQL query but I couldn´t get the expected result. I really don´t know what is going wrong.
I have a table Product which contains (product_id, title) and other table Product_Variation which contains (product_variation_id, product_id, description, gender, price)
Basically, I have a product. For each product, have N variations.
e.g
Product: title "I have no idea"
Product_Variation: description "T-Shirt", gender "Male", price "59.90"
What I need is select Product and Product_Variation showing only the product with the lowest price.
I don´t care if a product has t-shirt, jacket or anything else as variation. I just need to get the variation which has the lowest price.
My query is:
SELECT b.product_id, b.title, MIN(b.price) as price, b.gender
FROM (
SELECT p.product_id, p.title, MIN(pv.price) AS price, pv.gender
FROM products p
join product_variation pv ON pv.product_id = p.product_id
GROUP BY p.product_id, p.title, pv.price, pv.gender
) b
GROUP BY b.product_id, b.title, b.price, b.gender
Pls, see my example in SQL Fiddle
Thanks!
Since you're using SQL 2008 you can use ROW_NUMBER to find the row with the lowest price:
SELECT *
FROM products p
INNER JOIN
(SELECT
product_id,
Description,
Gender,
Price,
ROW_NUMBER() OVER(PARTITION BY product_id ORDER BY price) Row
FROM product_variation )
pv ON pv.product_id = p.product_id
AND Row = 1
If you have two variations with the same price you'll get one random row.
-- Solution #1
SELECT *
FROM
(
SELECT p.product_id, p.title,
pv.price, pv.gender,
ROW_NUMBER() OVER(PARTITION BY p.product_id ORDER BY pv.price) AS row_num
FROM products p
join product_variation pv ON pv.product_id = p.product_id
) src
WHERE src.row_num = 1
-- Solution #2
SELECT p.product_id, p.title,
x.price, x.gender
FROM products p
cross apply
(
SELECT TOP(1) pv.price, pv.gender
FROM product_variation pv
WHERE pv.product_id = p.product_id
ORDER BY pv.price
) x
You can use the rank() window function to order stuff within a partition (group), but giving equal items the same rank:
;With b as (
Select
p.product_id,
p.title,
pv.price,
pv.gender,
rank() over(partition by p.product_id order by pv.price) rk
From
products p
Inner Join
product_variation pv
On pv.product_id = p.product_id
)
Select
b.product_id,
b.title,
b.price,
b.gender
From
b
Where
rk = 1
If you only want one per product even if there are equal products, use row_number() instead of rank()
Example Fiddle

How do I select max date for each row from a subquery

Let's say I want to select the 3 bestsellers in a supermarket. To do this, I have to add each sale to get the total for each product:
SELECT TOP(3) *
FROM
(
SELECT
SUM(s.individual_sale) AS totalsales,
p.productID AS ID,
p.productName AS Name
FROM
sales s,
products p
WHERE
1=1
AND p.productID = s.productID
GROUP BY
p.productID,
p.productName
) AS top_sellers
ORDER BY
top_sellers.totalsales DESC
It then returns me something like this:
ID..|.Name.|.totalsales
55.|.milk....|.1000
24.|.candy.|.800
67.|.juice...|.500
Now I want to retrieve a 4th column containing the last sale from each of these items, like querying "MAX saledate" to each one. How do I accomplish that?
EDIT: Adding MAX(s.saledate) isn't helping. It retrieves a date like 01 Jan 2012 to all rows, but if I query MAX(s.saledate) individually for each entry of the table above, it returns the correct date... My question is, how can I add the column MAX(s.saledate) for each product, using the same query that shows the 3 bestsellers.
You could add max(s.saledate) to your query. The subquery is not needed. The syntax t1 join t2 on <predicate> is considered much more readable than from t1, t2 where <predicate>.
select top 3 sum(s.individual_sale) as totalsales
, p.productID as ID,
, p.productName as Name
, max(s.saledate) as MaxSaleDate
from sales s
join products p
on p.productID = s.productID
group by
p.productID
, p.productName
order by
sum(s.individual_sale) desc
SELECT TOP(3) *
FROM
(
SELECT
SUM(s.individual_sale) AS totalsales,
p.productID AS ID,
p.productName AS Name,
MAX(s.saledate) as MaxSaleDate
FROM
sales s,
products p
WHERE
1=1
AND p.productID = s.productID
GROUP BY
p.productID,
p.productName
) AS top_sellers
ORDER BY
top_sellers.totalsales DESC
Add MAX(saledate) to your exisitng query.
SELECT TOP(3) *
FROM
(
SELECT
SUM(s.individual_sale) AS totalsales,
p.productID AS ID,
p.productName AS Name,
MAX(saleDate)
FROM
sales s,
products p
WHERE
1=1
AND p.productID = s.productID
GROUP BY
p.productID,
p.productName
) AS top_sellers
ORDER BY
top_sellers.totalsales DESC