Hi I wonder if you can help with the following query , I am going around in circles trying to get the syntax correct.
I have two Tables Orders
OrderID | Product ID | LineTotal
1 ABC 2
2 CDE 3
2 DEF 1
and Products Table Containing the Weight and Cost
ProductID | Weight | Cost
ABC 1 1
CDE 2 2
DEF 1 0.5
So for each order ID I need to SUM the LineTotal the Weight and the Cost.
Thanks for some pointers on how to go about this as I am getting errors with joins and silly results
Thanks
It should be very simple if I got the task right:
SELECT o.OrderID, o.ProductID, sum = (o.LineTotal + p.Weight + p.Cost)
FROM ORDERS o
INNER JOIN PRODUCTS p on o.ProductID = p.ProductID
Try this.
Select t3.OrderID , SUM(t3.SUM1) As TotalSum
From (Select t1.*,t2.Weight,t2.Cost,t1.LineTotal+t2.Weight+t2.Cost AS Sum1
from Orders t1
INNER JOIN Products t2
ON t1.ProductID=t2.ProductID ) t3
Group BY t3.OrderID
Related
I tried to join some Products based on if they're in a table or not. I'm using MSSQL and I'm trying to do this to see if the category has some products.
simplified Query:
SELECT c.CategoryID, c.Name, p.ProductID
FROM Category AS c
JOIN Product AS p ON p.ProductID IN (
SELECT PrductID FROM exampleTable
)
ProductTable:
ProductID
CategoryID
1
1
2
1
3
2
4
4
The output I receive:
CategoryID
Name
ProductID
1
Cat1
1
1
Cat1
2
2
Cat2
3
4
Cat4
4
The expected output:
CategoryID
Name
ProductID
1
Cat1
1
2
Cat2
3
4
Cat4
4
I'm trying to only join a product if it's in the select statement and not join all products which have the same category id.
In pseudo code I'm trying to achive this:
JOIN Product AS p IF p.ProductID IN (Subquery)
Is this somehow possible?
Ed banga's answer is IMHO more elegant and perfoment but to be closer to what you proposed in your question, you can simply use a where clause.
SELECT c.CategoryID, c.Name, p.ProductID
FROM Category AS c
JOIN Product AS p ON p.CategoryID = c.CategoryID
WHERE p.ProductID IN (
SELECT PrductID FROM exampleTable
)
I have two following tables:
products_table
id name
1 productA
2 productB
3 productC
inventory_table
id product_id amount
1 1 200
2 1 300
3 2 100
4 3 200
5 2 500
And the result I would like to get is
name total
productA 500
productB 600
productC 200
How could this be achieved using sql query?
Seems easy, first subSELECT query makes sums, parent one joins the names.
SELECT pt.name, n.total
FROM
(SELECT SUM(it.amount) as total, it.product_id
FROM inventory_table it
GROUP BY it.productID) n JOIN
products_table pt ON pt.id = n.product_id
I would try joining the two tables and use aggregation as
SELECT
p.name,
SUM(i.amount)
FROM product_table as p
LEFT JOIN inventory_table as i
ON p.id = i.product_id
GROUP by p.name
This is a simple inner join between the two tables, grouping by each Product and summing all its values.
select p.[name], Sum(i.amount) Amount
from product_table p join inventory_table i on i.product_id=p.id
group by p.[name]
I have the following tables
Location (Id, locationName)
Inventory (productid, qty, locationid)
With the following data, I need to query to show all locations per productid, even when not in inventory table. example of records below.
Table Location
Id Location Name
--------------------
1 Plant
2 Warehouse
3 Container
Table Inventory:
Productid Qty Locationid
-----------------------------
45 30 1
45 56 2
3 15 1
3 50 3
15 25 3
Desired result for my query:
Productid Qty LocationName
---------------------------------
45 30 Plant
45 56 Warehouse
45 0 Container
3 15 Plant
3 0 Warehouse
3 50 Container
15 0 Plant
15 0 Warehouse
15 25 Container
So far I have tried many different ways but no luck, so any help will be appreciated.
You can use the following query:
SELECT p.ProductId,
COALESCE(qty,0) AS qty,
[Location Name]
FROM LOCATION l
CROSS JOIN (SELECT DISTINCT ProductId FROM Inventory) AS p
LEFT JOIN Inventory i ON l.Id = i.locationid AND p.Productid = i.Productid
ORDER BY Productid, [Location Name]
The query uses CROSS JOIN to get all possible combinations between locations and products.
Demo here
Select y., isNull(z.Quantity,0) as Quantity
From
(
Select Location., x.ProductId
From Location,(Select Distinct ProductId From Inventory) as x
) as y
Left Outer Join Inventory z ON y.Id = z.LocationId
and y.ProductId = z.ProductId
I am struggling to get my head around this sql.
I have a function that returns a list of items associated with a Bill of Materials BOM.
The result of the sql select
SELECT
BOM,
ITEMID,
QTY
FROM boms
WHERE
bom='A'
is
BOM | ITEMID | QTY
A | ITEMB | 1
A | ITEMC | 2
Now using that result set I am looking to query my salestable to find sales where ITEMB and ITEMC were sold in enough quantity.
The format of the salestable is as follows
SELECT
salesid,
itemid,
sum(qtyordered) 'ordered'
FROM salesline
WHERE
itemid='ITEMB'
or itemid='ITEMC'
GROUP BY salesid, itemid
This would give me something like
salesid | itemid | ordered
SO-10000 | ITEMB | 1
SO-10001 | ITEMB | 1
SO-10001 | ITEMC | 1
SO-10002 | ITEMB | 1
SO-10002 | ITEMC | 2
ideally I would like to return only SO-10002 as this is the only sale where all necessary units were sold.
Any suggestions would be appreciated. Ideally one query would be ideal but I am not sure if that is possible. Performance is not a must as this would be run once a week in the early hours of the morning.
EDIT
with the always excellent help, the code is now complete. I have wrapped it all up into a UDF which simply returns the sales for a specified BOM over a specified period of time.
Function is
CREATE FUNCTION [dbo].[BOMSALES] (#bom varchar(20),#startdate datetime, #enddate datetime)
RETURNS TABLE
AS
RETURN(
select count(q.SALESID) SOLD FROM (SELECT s.SALESID
FROM
(
SELECT s.SALESID, ITEMID, SUM(qtyordered) AS SOLD
FROM salesline s inner join SALESTABLE st on st.salesid=s.SALESID
where st.createddate>=#startdate and st.CREATEDDATE<=#enddate and st.salestype=3
GROUP BY s.SALESID, ITEMID
) AS s
JOIN dbo.BOM1 AS b ON b.ITEMID = s.ITEMID AND b.QTY <= s.SOLD
where b.BOM=#bom
GROUP BY s.SALESID
HAVING COUNT(*) = (SELECT COUNT(*) FROM dbo.BOM1 WHERE BOM = #bom)) q
)
This should return all sales with an exact match, i.e. same itemid and same quantity:
SELECT s.salesid
FROM
(
SELECT salesid, itemid, SUM(qtyordered) AS ordered
FROM salesline AS s
GROUP BY salesid, itemid
) AS s
JOIN
boms AS b
ON b.itemid = s.itemid
AND b.QTY = s.ordered
WHERE b.BOM='A'
GROUP BY s.salesid
HAVING COUNT(*) = (SELECT COUNT(*) FROM boms WHERE BOM='A');
If you want to return a sale where the quantity is greater than boms.qty youhave to change the join accordingly:
JOIN
boms AS b
ON b.itemid = s.itemid
AND b.QTY <= s.ordered
Untested...
You can do this aggregation and a having clause:
select salesid
from salesline sl
group by salesid
having sum(case when itemid = 'ITEMB' then 1 else 0 end) > 0 and
sum(case when itemid = 'ITEMA' then 1 else 0 end) > 0;
Each condition in the having clause is counting the number of rows with each item.
I think this may get you the results you need. You'll have to replace #BOM with your bom:
SELECT
DISTINCT salesid
FROM
salesline sl
INNER JOIN boms b ON
b.bom = #BOM
AND b.itemid = sl.itemid
GROUP BY salesid, itemid
HAVING SUM(qtyordered) >= b.qty
From what I gather, the first query is used to get the thresholds for returning qualifying sales? Based on your example data rows I assumed that there will only be one line per salesid + itemid (basically acting as a dual field primary key) in the salesline table? If that is true I don't think there is a need to do a SUM as you have in your second example query. Let me know if I'm mistaken in any of my assumptions and I'll adjust my answer.
i have 3 tables Product Category and ProductCategory.
Product table:
ProductID ProductName
1 P1
2 P2
3 P3
Category table:
CategoryID CategoryName
1 C1
2 C2
3 C3
ProductCategory:
ProductID CategoryID
1 1
1 2
1 3
2 3
3 1
3 2
I need a query which returns products which fall under more than 1 categories. Based on the table data above the result would be:
ProductID ProductName
1 P1
3 P3
So i wrote a query to fetch all the ProductID's which have more than one CategoryID's as below:
select ProductID,count(CategoryID)
from ProductCategory
group by Productid
having count(CategoryID)>1)
But when i try to display product details using the below query i get an error:
select *
from Product
where ProductID in (
select ProductID,count(CategoryID)
from ProductCategory
group by Productid
having count(CategoryID)>1))
Is my query wrong? How do i get the required product details which fall in more than one categories?
Remove the COUNT() in the subquery. The result of the subquery when used on IN clause must have only one returned column.
SELECT *
FROM Product
WHERE ProductID IN
(
SELECT ProductID
FROM ProductCategory
GROUP BY Productid
HAVING count(CategoryID) > 1
)
SQLFiddle Demo
or by using JOIN
SELECT a.*
FROM Product a
INNER JOIN
(
SELECT ProductID
FROM ProductCategory
GROUP BY Productid
HAVING count(CategoryID) > 1
) b ON a.ProductID = b.ProductID
SQLFiddle Demo
You can try use CROSS APPLY Operator in SQL Server
SELECT DISTINCT C.ProductID,C.ProductName,A.CategoryID,A.Total
FROM Product C
CROSS APPLY (
Select CA.CategoryID,Total=COUNT(*)
From ProductCategory CA
Where C.ProductID=CA.ProductID
Group By CA.CategoryID Having COUNT(*)>1
) AS A
ORDER BY A.Total DESC
Take a look: http://explainextended.com/2009/07/16/inner-join-vs-cross-apply/