SQL Problem : Query - sql

I have an issue in query. I have tables product, stockRecord and priceDetail. I want to display all products. If the price is not defined in priceDetail for that product, then it will be 0.00; similarly if the quantity is not defined in stockRecord table, then the quantity should be 0.
But if the price is defined in the priceDetail table, then we should get the latest price from the table
WMProduct
BusinessUnit ProductCode Description SalableFlag
MASS 0001 Pen 1
MASS 0002 Computer 1
MASS 0003 Book 1
MASS 0004 Bottle 1
WMStockRecord
ProductCode AvailableQuantity
0001 10
0003 15
WMPriceDetail
ProductCode DateFrom DateTo Price
0001 10-10-2009 10-10-2011 100
0001 10-12-2009 10-10-2010 80
0001 12-12-2010 01-12-2011 120
0002 12-01-2010 '' 200
0004 12-12-2010 12-05-2011 100
I need list of products like this:
BusinessUnit ProductCode Description SalableFlag Price AvailableQuantity
MASS 0001 Pen 1 120 10
MASS 0002 Computer 1 200 0
MASS 0003 Book 1 0.00 15
MASS 0004 Bottle 1 0.00 0

Try using sub query and left join like below :
SELECT P.ProductCode AS ProductCode,
P.Description AS ProductName,
P.SalableFlag AS Salable,
ISNULL(STK.AvailableQuantity, 0) AS Qty,
ISNULL((SELECT TOP 1 Price FROM WMPriceDetail
WHERE ProductCode = P.ProductCode ORDER BY DateTo DESC), 0) AS Price
FROM WMProduct P
LEFT JOIN WMStockRecord STK ON P.ProductCode = STK.ProductCode

Related

Remove duplicated results using inner join?

I want to see TotalSale values ONLY on the first row of TotalSale that matches with PricesTable DocNumber and DocType
SalesTable
ProductID DocType DocNumber UnitPrice
01 A 000001 150.00
05 A 000001 200.00
06 A 000001 80.00
65 C 002550 15000.00
30 B 002551 100.00
and
PricesTable
DocType DocNumber TotalSale
A 000001 430.00
C 002550 15000.00
B 002551 100.00
What I want to get is something like this
TotalSalesTable
ProductID DocType DocNumber UnitPrice TotalSale
01 A 000001 150.00 430.00
05 A 000001 200.00
06 A 000001 80.00
65 C 002550 15000.00 15000.00
30 B 002551 100.00 100.00
but instead I keep getting this:
TotalSalesTable
ProductID DocType DocNumber UnitPrice TotalSale
01 A 000001 150.00 430.00--> Good Value
05 A 000001 200.00 430.00--> This
06 A 000001 80.00 430.00--> and this are duplicated
65 C 002550 15000.00 15000.00
30 B 002551 100.00 100.00
This is the query I'm using:
SELECT ST.ProductID
,ST.DocType
,ST.DocNumber
,ST.UnitPrice
,PT.TotalSale
from SalesTable ST
INNER JOIN PricesTable PT
on (ST.DocNumber=PT.DocNumber)
I think you can try enumerating all the rows, then assign totalsales value only to those rows that are first for every docnumber:
SELECT ST.ProductID
,ST.DocType
,ST.DocNumber
,ST.UnitPrice
,case when row_number() over
(partition by st.docnumber order by st.productid) = 1
then PT.TotalSale end as TotalSale
from SalesTable ST
INNER JOIN PricesTable PT
on (ST.DocNumber=PT.DocNumber)
Edit: I would also recommend having two columns: one with a duplicated values for every docnumber, and another one with those values hidden except the first one. So that in future you can calculate ratios and aggregates from the output more comfortably.
You can get the required results without the need of the second table (PricesTable),
Select ProductID, DocType, DocNumber, UnitPrice,
Case When ROW_NUMBER() Over (Partition By DocType, DocNumber Order By ProductID) = 1
Then SUM(UnitPrice) Over (Partition By DocType, DocNumber)
Else ''
End as TotalSale
From SalesTable
See a demo from db<>fiddle.

Retrieve all records if no record exist in the joining table

I have these three tables,
PO_HEADER
po_number
vendor_name
10001
Xyz
100002
ABC
PO_LINEITEM
line_number
po_number
item_quantity
recieved_quantity
0001
10001
20
10
0002
10001
80
10
0002
10002
40
35
SHIPMENT_LINEITEM
line_number
po_number
shipping_quant
0001
10001
20
How to retrieve order_master based on these two conditions
if any po_lineitem having item_quantity > recieved quantity.
if po_lineitem having item_quantity > (sum of previously shippingquantity from asn_lineitem for same line_number & poNumber) .2(b) if there no items in the asn_lineitem this should return true.
I wrote this query but was not able to achieve 2(b)
select count(*) from erp_po_header
where po_number in
(select erlitms.po_number from erp_po_line_items erlitms
JOIN
(select sum(shipping_quantity) as total_prev_shipped_items,po_number,item_number from
asn_lineitem
Group by po_number,item_number)
asn_items
ON erlitms.po_number = asn_items.po_number
and erlitms.item_number = asn_items.item_number
and erlitms.item_quantity > CAST (erlitms.received_quantity AS INTEGER)
and erlitms.item_quantity > asn_items.total_prev_shipped_items )

Discount Present Update When Quantity Change

I have table call tblInvoice. This is my table with some data.
InvoiceNo
ItemName
Quantity
CostPrice
ItemCode
DiscountPrice
DisPresent
Amount
GrossAmount
SalePrice
INV01
80= BK
10
30.00
EX80=
40.00
100.00
400.00
575.00
50.00
INV01
80= BK
5
30.00
EX80=
35.00
75.00
175.00
575.00
50.00
My client is sell same item with different price. as you can see here DiscountPrice is different but ItemName and ItemCode is same. When return product after sold I want to subtraction quantity. Its ok I already done that part. But problem is I want to update DiscountPesent after return product. its like this. Imagine I return 1 Book DiscountPrice is 40.00. Not 35.00. I want to update only first row. not both rows. I want to get DiscountPresent Like this.
SalePrice - DiscountPrice * Quantity = DiscountPresent
According to the above table. Imagine I subtraction 1 Quantity from DiscountPrice 40.00 row. now My Quantity is 9 I want to get DiscountPresent Like this.
50 - 40 = 10 * 9 = 90
I used following query for achieve this. sometimes its work as expected. but sometimes DiscoutPresent Switching with second row DiscountPeresent. After that table look like this.
InvoiceNo
ItemName
Quantity
CostPrice
ItemCode
DiscountPrice
DisPresent
Amount
GrossAmount
SalePrice
INV01
80= BK
9
30.00
EX80=
40.00
75.00
400.00
575.00
50.00
INV01
80= BK
5
30.00
EX80=
35.00
90.00
175.00
575.00
50.00
90 is come to second row. 75 is come to first row. its wrong. I used following code. sometimes its work as expected. but sometimes it switching DiscountPresent.
UPDATE ps
SET DisPresent = ((i.SalePrice) - (i.DiscountPrice)) * (i.Quantity)
FROM tblInvoice ps JOIN
(SELECT i.InvoiceNo, i.DiscountPrice, i.Quantity, i.SalePrice FROM tblInvoice i
GROUP BY i.DiscountPrice, i.InvoiceNo, i.Quantity, i.SalePrice)i
ON ps.InvoiceNo = i.InvoiceNo
looks to me you only need a simple update statement
UPDATE i
SET DisPresent = (i.SalePrice - i.DiscountPrice) * i.Quantity
FROM tblInvoice i
if this is not what you wanted, please show the expected result for the sample data that you have provided
if you are returning any product you should update only that invoice
UPDATE ps
SET DisPresent = ((i.SalePrice) - (i.DiscountPrice)) * (i.Quantity)
FROM tblInvoice where invoiceid=1 and itemcode='EX80='

SQL Duplicate Values Issue on LEFT OUTER JOIN

I am trying to do a Join within 4 tables but it is returning duplicate rows. Some Items might not exist on Sales and Inventory tables. What needs to be done to resolve the issue;
ProductList (We need all the items)
Item_ID
ProductDetail (it has the return all the matching items from Product List)
Item_ID
Product_Name
Sales (needs to return all matching items from ProductList)
Item_ID
Sales_Qty
Inventory
Item_ID
Remaining_Qty
SAMPLE DATA
ProductList
Item_Id
--------
0001
0002
0003
0004
ProductDetail
Item_Id Product_Name
-----------------------
0001 Eraser
0002 Pencil
0003 Pen
0004 Mouse
0005 Keyboard
0006 Monitor
0007 Cable
Sales
Item_ID Sales_Qty
--------------------
0001 15
0002 20
0004 50
0005 60
0006 45
Inventory
Item_ID Remaining
-------------------
0001 100
0002 95
0003 55
0005 101
0006 13
0007 18
Desired output:
Item_Id Item_Name Sales_Qty Remaining_Qty
--------------------------------------------------
0001 Eraser 15 100
0002 Pencil 20 95
0003 Pen 0 55
0004 Mouse 50 0
My query :
SELECT *
FROM ProductList a
INNER JOIN ProductDetail b ON a.Item_ID = b.ItemID
LEFT JOIN Sales c ON a.Item_Id = c.Item_ID
LEFT JOIN Inventory d ON a.Item_ID = d.Item_ID
You can use DISTINCT
SELECT DISTINCT a.Item_ID, *
FROM ProductList a
INNER JOIN ProductDetail b
ON a.Item_ID = b.ItemID
LEFT JOIN Sales c
ON a.Item_Id = c.Item_ID
LEFT JOIN Inventory d
ON a.Item_ID = d.Item_ID
Please try this:
SELECT a.Item_Id, b.product_Name, c.Sales_Qty, d.Remaining_Qty
FROM ProductList a
LEFT JOIN ProductDetail b
ON a.Item_ID = b.Item_ID
LEFT JOIN Sales c
ON a.Item_Id = c.Item_ID
LEFT JOIN Inventory d
ON a.Item_ID = d.Item_ID
This will produce this output:
Item_Id product_Name Sales_Qty Remaining_Qty
---------------------------------------------------
0001 Eraser 15 100
0002 Pencil 20 95
0003 Pen NULL 55
0004 Mouse 50 NULL
If you don't want nulls to be returned, then use COALESCE (if your database is sql server, you can use ISNULL instead of COALESCE) as shown below:
SELECT a.Item_Id, b.product_Name, COALESCE(c.Sales_Qty, 0), COALESCE(d.Remaining_Qty, 0)
FROM ProductList a
LEFT JOIN ProductDetail b
ON a.Item_ID = b.Item_ID
LEFT JOIN Sales c
ON a.Item_Id = c.Item_ID
LEFT JOIN Inventory d
ON a.Item_ID = d.Item_ID
This will produce this output:
Item_Id Item_Name Sales_Qty Remaining_Qty
--------------------------------------------------
0001 Eraser 15 100
0002 Pencil 20 95
0003 Pen 0 55
0004 Mouse 50 0

Applying percent change based on unique identifier

I'm calculating margins from a sales table in SQL and I need to reduce sales amounts if there is a discount in a sale based on it's invoice number. For this sample a 25% discount is applied Invoice 123. The total sales amount for invoice 123 is $100.00 but there is a 25% discount applied to that amount. What I want to do is apply that 25% discount to all sales numbers for invoice 123 so I can get the actual revenue number.
Sample Data:
ID Type ProductType Amount
123 Sale Jeans 50.00
123 Sale T-Shirt 30.00
123 Sale Sock 20.00
123 Discount - 25% NULL -25.00
456 Sale Jeans 60.00
456 Sale T-Shirt 40.00
456 Sale Sock 70.00
Expected Result:
ID Type ProductType Amount Actual Amount
123 Sale Jeans 50.00 41.67
123 Sale T-Shirt 30.00 21.67
123 Sale Sock 20.00 11.67
123 Discount - 25% NULL -25.00 0.00
456 Sale Jeans 60.00 60.00
456 Sale T-Shirt 40.00 40.00
456 Sale Sock 70.00 70.00
I've tried creating a new column where I multiple the amount times the discount rate but I can't get the numbers correct because it needs to be applied to the invoice number each discount corresponds to.
I'd like to have a new column that shows the adjusted amount based on the discount rate and then the discount amount showing zero.
One way is to use window functions to calculate the sum of the negative values for an id divided by the number of non negative values for that id by CASE expressions as arguments to the functions. The result of the division can than be deducted from the price. Additionally use a CASE to get zero for the negative values.
SELECT t1.id,
t1.amount,
CASE
WHEN t1.amount <= 0 THEN
0
ELSE t1.amount
+ sum(CASE
WHEN t1.amount < 0 THEN
t1.amount
ELSE
0
END) OVER (PARTITION BY t1.id)
/
count(CASE
WHEN t1.amount >= 0 THEN
1
END) OVER (PARTITION BY t1.id)
END actual_amount
FROM elbat t1;
db<>fiddle