I have 3 table stock,inward,issue
Stock table's columns and data :
part_no | part_name | totalqty
10100 ciol 30
112233 abc 20
123456 coper 50
inward table :
part_no | qty
123456 10
123456 20
10100 20
112233 15
10100 25
issue table :
part_no | qty
112233 20
112233 15
123456 10
112233 25
10100 40
10100 20
my desired output :
part_no | part_name |inwardQty |issueQty
10100 coil 45 60
112233 abc 15 60
123456 coper 30 10
following is the query i have written,but not giving my desired output
select s.part_no,s.part_name,sum(i.qty) as inwardQty,sum(p.qty)as issueQty
from stock s
left join inward i on s.part_no = i.part_no
left join issue p on s.part_no = p.part_no
group by
s.part_no,s.part_name
getting following output by this query :
part_no | part_name |inwardQty |issueQty
10100 coil 90 120
112233 abc 45 60
123456 coper 30 20
The problem is that you're matching every row for inward with every row for issue, for which they're dealing with the same part. I think subqueries would be best here:
select s.part_no,s.part_name,i.qty as inwardQty,p.qty as issueQty
from stock s
left join
(select part_no,sum(qty) as qty from inward group by part_no) i on s.part_no = i.part_no
left join
(select part_no,sum(qty) as qty from issue group by part_no) p on s.part_no = p.part_no
So now, there's only one (or zero) rows to join in each of the joins, and you don't get a cartesian product.
Try this query:
SELECT
s.part_no, s.part_name,
InwardQty = (SELECT SUM(qty) FROM #inward i WHERE i.part_no = s.part_no),
IssueQty = (SELECT SUM(qty) FROM #issue p WHERE p.part_no = s.part_no)
FROM
dbo.stock s
GROUP BY
s.part_no, s.part_name
Gives me exactly your desired output.
Related
I have 4 Tables in PostgreSQL with the following structure as you can see below:
"Customers"
ID | NAME
101 Max
102 Peter
103 Alex
"orders"
ID | customer_id | CREATED_AT
1 101 2022-05-12
2 101 2022-06-14
3 101 2022-07-9
4 102 2022-02-14
5 102 2022-06-18
6 103 2022-05-22
"orderEntry"
ID | order_id | product_id |
1 3 10
2 3 20
3 3 30
4 5 20
5 5 40
6 6 20
"product"
ID | min_duration
10 P10D
20 P20D
30 P30D
40 P40D
50 P50D
Firstly I need to select "orders" with the max(created_at) date for each customer this is done with the query (it works!):
SELECT c.id as customerId,
o.id as orderId,
o.created_at
FROM Customer c
INNER JOIN Orders o
ON c.id = o.customer_id
INNER JOIN
(
SELECT customer_id, MAX(created_at) Max_Date
FROM Orders
GROUP BY customer_id
) res ON o.customer_id = res.customer_id AND
o.created_at = res.Max_date
the result will look like this:
customer_id | order_id | CREATED_AT
101 3 2022-07-9
102 5 2022-06-18
103 6 2022-05-22
Secondly I need to select for each order_id from "orderEntry" Table, "products" with the max(min_duration) the result should be:
order_id | max(min_duration)
3 P30D
5 P40D
6 P20D
and then join results from 1) and 2) queries by "order_id" and the total result which I'm trying to get should look like this:
customer_name | customer_id | Order_ID | Order_CREATED_AT | Max_Duration
Max 101 3 2022-07-9 P30D
Peter 102 5 2022-06-18 P40D
Alex 103 6 2022-05-22 P20D
I'm struggling to get query for 2) and then join everything with query from 1) to get the result. Any help I would appreciate!
You could make the first query to an CTE and use that to join the rest of the queries.
Like this.
WITH CTE AS ( SELECT c.id as customerId,
o.id as orderId,
o.created_at
FROM Customer c
INNER JOIN Orders o
ON c.id = o.customer_id
INNER JOIN
(
SELECT customer_id, MAX(created_at) Max_Date
FROM Orders
GROUP BY customer_id
) res ON o.customer_id = res.customer_id AND
o.created_at = res.Max_date)
SELECT customerId,orderId,created_at,p.min_duration
FROM CTE
JOIN (SELECT "orderId", MAX("product_id") as product_id FROM "orderEntry" GROUP BY orderId) oe ON CTE.orderId = oe.orderId
JOIN "product" pr ON oe.product_id = pr."ID"
I am running a query on two tables that needs to return the total number of lines in each sales order and a total of the items ordered.
A simplified version of the SalesOrder table is constructed like this:
SalesOrderID
Customer
SODate
102
Bob Smith
12/15/2021
101
Jane Doe
12/05/2021
100
Sarah Joy
12/01/2021
The second table, SalesOrderLine, contains the line items in the sales order:
SalesOrderID
LineNumber
Item
Quantity
100
1
Nuts
5
100
2
Bolts
10
100
3
Washers
3
101
1
Screws
15
102
1
Nails
25
102
2
Hooks
5
The result of the query would look like this:
SalesOrderID
SODate
Customer
TotalLines
TotalItems
102
12/15/2021
Bob Smith
2
30
101
12/05/2021
Jane Doe
1
15
100
12/01/2021
Sarah Joy
3
18
I am locking up on how to use the query to return the Total Number of Lines and Total Number of Items per SalesOrderID.
SELECT SalesOrder.SalesOrderID, SalesOrder.SODate, SalesOrder.SOCustomer
?? Total Number of Lines and Total Number of Items ??
FROM SalesOrder
INNER JOIN SalesOrders ON SalesOrder.SalesOrderID = SalesOrderLine.SalesOrderID
ORDER BY SalesOrderID
You can use apply :
select so.*, soo.*
from salesorder so cross apply
( select count(*) as Totallines, sum(soo.quantity) as TotalQty
from SalesOrders soo
where soo.SalesOrderID = so.SalesOrderID
) soo;
You are almost done, except the aggregation.
Query
select so.SalesOrderID, so.SODate, so.SOCustomer,
count(sol.LineNumber) as TotalLines, sum(sol.Quantity) as TotalItems
from SalesOrder as so
join SalesOrderLine as sol
on so.SalesOrderID = sol.SalesOrderID
group by so.SalesOrderID, so.SODate, so.SOCustomer
order by SalesOrderID;
I have a control table, where Prices with Item number are tracked date wise.
id ItemNo Price Date
---------------------------
1 a001 100 1/1/2003
2 a001 105 1/2/2003
3 a001 110 1/3/2003
4 b100 50 1/1/2003
5 b100 55 1/2/2003
6 b100 60 1/3/2003
7 c501 35 1/1/2003
8 c501 38 1/2/2003
9 c501 42 1/3/2003
10 a001 95 1/1/2004
This is the query I am running.
SELECT pr.*
FROM prices pr
INNER JOIN
(
SELECT ItemNo, max(date) max_date
FROM prices
GROUP BY ItemNo
) p ON pr.ItemNo = p.ItemNo AND
pr.date = p.max_date
order by ItemNo ASC
I am getting below values
id ItemNo Price Date
------------------------------
10 a001 95 2004-01-01
6 b100 60 2003-01-03
9 c501 42 2003-01-03
Question is, is my query right or wrong? though I am getting my desired result.
Your query does what you want, and is a valid approach to solve your problem.
An alternative option would be to use a correlated subquery for filtering:
select p.*
from prices p
where p.date = (select max(p1.date) from prices where p1.itemno = p.itemno)
The upside of this query is that it can take advantage of an index on (itemno, date).
You can also use window functions:
select *
from (
select p.*, rank() over(partition by itemno order by date desc) rn
from prices p
) p
where rn = 1
I would recommend benchmarking the three options against your real data to assess which one performs better.
Tables Diagram
These are my datas from 3 tables.
select*from ShippingDetails
ProductCode Shipping Quantity
MFD01-10 50
MFD01-07 50
MFD01-10 10
select*from ProductDetails
ProductCode Shipping Quantity
MFD01-07 500
MFD01-10 100
MFD01-07 1000
MSD01-21 200
select*from StockData
ProductCode UrunAdi ( " Product Name")
MFD01-07 7 mm FTube
MFD01-10 10 mm FTube
MSD01-21 21 mm STube
MSD01-27 27 mm STube
I try to write these two queries but it didnt work. I couldn't merge as one table.
select StockData.ProductCode,SUM( ProductDetails.ProductQuantity) as ' Product Quantity' from ProductDetails RIGHT OUTER JOIN StockData on ProductDetails.ProductCode=StockData.ProductCode group by StockData.ProductCode
Product Code Product Quantity
MFD01-07 1500
MFD01-10 100
MSD01-21 200
MSD01-27 NULL
select StockData.ProductCode, SUM ( ShippingDetails.ShippingQuantity) as ' Shipping Quantity' from ShippingDetails RIGHT OUTER JOIN StockData on ShippingDetails.ProductCode=StockData.ProductCode group by StockData.ProductCode
Product Code Shipping Quantity
MFD01-07 50
MFD01-10 60
MSD01-21 NULL
MSD01-27 NULL
This result that i need. Which query would give it? I will appreciate if you solve my issue.
Product Code (Product-Shipping) Quantity
MFD01-07 1450
MFD01-10 40
MSD01-21 200
MSD01-27 NULL
You need a subquery for each table and then join together to calculate the total.
SQL Fiddle Demo
SELECT SD.[ProductCode],
COALESCE(PD.stock, 0) - COALESCE(D.sales, 0) as [(Product-Shipping) Quantity]
FROM StockData SD
LEFT JOIN (SELECT [ProductCode], SUM([Product Quantity]) stock
FROM ProductDetails
GROUP BY [ProductCode]) PD
ON SD.[ProductCode] = PD.[ProductCode]
LEFT JOIN (SELECT [ProductCode], SUM([Shipping Quantity]) sales
FROM ShippingDetails
GROUP BY [ProductCode]) D
ON SD.[ProductCode] = D.[ProductCode]
OUTPUT
| ProductCode | (Product-Shipping) Quantity |
|-------------|-----------------------------|
| MFD01-07 | 1450 |
| MFD01-10 | 40 |
| MSD01-21 | 200 |
| MSD01-27 | 0 |
I have a table that contains:
ITEMID COSTAMOUNTPOSTED QTY DATEPHYSICAL
10001 20 20 2014-10-01
10001 30 20 2014-10-20
10005 20 20 2014-10-01
10005 20 30 2014-10-15
I want to select the last physical action with the item, the result I want to get is:
ITEMID COSTAMOUNTPOSTED QTY DATEPHYSICAL
10001 30 20 2014-10-20
10005 20 30 2014-10-15
The query I run :
SELECT itemid,costamountposted,qty,datephysical
FROM A
where datephysical =(select max(datephysical)
FROM A
But I only get result with items that have biggest physical date. Any suggestions?
You can do this using subquery,
SELECT a.*
FROM tableName a
INNER JOIN
(
SELECT ITEMID , MAX(DATEPHYSICAL) max_date
FROM tableName
GROUP BY ITEMID
) b ON a.ITEMID = b.ITEMID AND a.DATEPHYSICAL = b.max_date