Remove Row Data If Qty Zero - sql

I have a data like this in Table Receipts, for the plus value is the amount of receipt of goods while the negative value in case of returns.
In the picture above, the Receiver_No 01267A is the receipt of the first item with Qty_Received 1. Then there is the return of goods on the receipt number of goods 01268A. I want this transaction not to show up.
Here's statement where i have tried.
select I2.Receiver_No,
I2.Purchase_order,
I2.PO_Line,
I2.Qty_received
from (Select Purchase_order,
PO_Line
from Receipts
group by Purchase_order,
PO_Line
having sum(qty_received) <>'0') I1 inner join
Receipts I2 On
I1.Purchase_Order = I2.Purchase_Order and
I1.PO_Line = I2.PO_Line
But the result did not meet with i want.
Please Help.

This will work for the very limited data that you have provided. If you care to provide more information about what the data looks like, then it will be easier to come up with a better solution.
If you have data with a lot of lines that have identical quantities, then this solution will not work.
SELECT
r.Receiver_No, r.Purchase_order, r.PO_Line, r.Qty_received
FROM
receipts r
WHERE
NOT EXISTS (SELECT
purchase_order
FROM
receipts s
WHERE
r.qty_received = -s.qty_received
)

If your requirement is to fetch rows with quantities less than one and not the negative ones :
SELECT * FROM Receipts WHERE ABS(QtyRecvd) >0 AND ABS(QtyRecvd) < 1

Try This
SELECT * FROM Receipts where Qty_received>0 AND Qty_received < 1

Related

Summing Data on Two Rows with a Similar Identifier

I'm attempting to sum a column 'Quantity' in our database whenever an Item ID is either itself or if its itself with a zero in front (whether the ID is 2447 or 02447 as an example in this case):
I started with the following to get the sums of the IDs:
SELECT
"TJ_TransactionJournalDetail"."TLI_ScanCode" As LineItemID,
"TJ_StockInventory"."INV_ScanCode" As InventoryID,
"TJ_TransactionJournalDetail"."TLI_ReceiptAlias" As ReceiptAlias,
"TJ_StockInventory"."INV_Name" As ItemName,
"TJ_TransactionJournalDetail"."TLI_LIT_FK" As LineDiscount,
SUM("TJ_TransactionJournalDetail"."TLI_Quantity") AS Quantity
FROM "TJ_StockInventory" LEFT OUTER JOIN "TJ_TransactionJournalDetail" ON "TJ_StockInventory"."INV_PK" = "TJ_TransactionJournalDetail"."INV_PK"
WHERE ecrs.TJ_TransactionJournalDetail.TLI_StartTime > '2020-01-17 00:00:00.000'
AND ecrs.TJ_TransactionJournalDetail.TLI_EndTime < '2020-01-19 23:59:59.999'
AND INV_DPT_FK = 49
AND "TJ_TransactionJournalDetail"."TLI_LIT_FK" = 1
GROUP BY LineItemID,InventoryID,ReceiptAlias,ItemName,LineDiscount
ORDER BY InventoryID;
These are the results the quantity of which I'm attempting to combine:
LineItemID,InventoryID,ReceiptAlias,ItemName,LineDiscount,Quantity
'2447','02447 ','DELI-BEAR CLAW EA','Bear Claw',1,1.0000
'02447','02447 ','DELI-BEAR CLAW EA','Bear Claw',1,30.0000
What I'm looking for:
'2447','02447 ','DELI-BEAR CLAW EA','Bear Claw',1,31.0000
-or-
'02447','02447 ','DELI-BEAR CLAW EA','Bear Claw',1,31.0000
as long as the quantity is 31.
I basically want to combine the quantity of two rows if the LineItemID is the same as "0" concatenated with the LineItemID on another line. Or another way of possibly accomplishing it would be to combine all items with the same InventoryID, but that is in the StockInventory table, not the TransactionJournal table which has the quantity that I'm summing.
And have tried a number of solutions, first I tried a CASE statement but couldn't figure out how to apply it across rows:
....
SUM (
CASE WHEN ( "TJ_StockInventory"."INV_ScanCode" = STRING('0',"TJ_TransactionJournalDetail"."TLI_ScanCode",' ') )
THEN "TJ_TransactionJournalDetail"."TLI_Quantity"
ELSE 0 END
) AS Quantity
FROM "TJ_StockInventory" LEFT OUTER JOIN
....
I also tried partitioning by ItemID to combine the quantity when the InventoryIDs were the same:
....
SUM("TJ_TransactionJournalDetail"."TLI_Quantity") over (partition by "TJ_StockInventory"."INV_ScanCode") AS Quantity
....
But neither of these solutions worked. I chose to "else 0" the case statement just to narrow it down to that one item, but in all cases it kept the lines separate and did not combine the quantities.
I've looked at a number of tutorials but none seem to deal with this specific case, and I haven't found anything that was hinting at a solution for this. That being said, I have difficulty wrapping my mind around database programming at times and am open to the idea that I may be approaching this in the incorrect way.
A couple of pseudocode examples of what I'm looking for
if LineItemID of this row = CONCAT('0', LineItemID) of another row
then sum the quantities of those rows
-or-
if InventoryID of this row and InventoryID of another row are equal
then sum them even if the LineItemIDs are different
Any help, pointers or directions to examples or docs online that could help with this would be great!
Thank you!
You seem to want to remove "LineItemID" from the aggregation:
SELECT MAX(tjd."TLI_ScanCode") As LineItemID,
si."INV_ScanCode" As InventoryID,
tjd."TLI_ReceiptAlias" As ReceiptAlias,
si."INV_Name" As ItemName,
tjd."TLI_LIT_FK" As LineDiscount,
SUM(tjd."TLI_Quantity") AS Quantity
FROM "TJ_StockInventory" si LEFT OUTER JOIN
"TJ_TransactionJournalDetail" tjd
ON si."INV_PK" = tjd."INV_PK"
WHERE tjd.TLI_StartTime > '2020-01-17' AND
tjd.TLI_EndTime < '2020-01-20' AND
INV_DPT_FK = 49 AND
tjd."TLI_LIT_FK" = 1
GROUP BY InventoryID, ReceiptAlias, ItemName, LineDiscount
ORDER BY InventoryID;

Access 2013 SQL, three tables, two using sum wrong results

Can someone please help me with this issue? I've scoured the Internet looking at dozens of examples, but i just can't find a solution that works.
I am using Access 2013. The problem is that I am trying to make a query that will highlight all part numbers from a supplier that either has customer back orders and/or overdue deliveries.
I am using three tables:
tbl_Inventory_Master which I require the part number, on hand stock value, and the supplier code.
For any back orders I need to join the tbl_Customer_Back_Order table as I need the count of back order lines and the sum of the back order quantity.
If the supplier has a late delivery, then I need to add the tbl_On_Order table showing the count of overdue deliveries and the sum of the overdue quantities.
The query is retrieving the data but the returned quantities are double what they should be.
SELECT
I.Inventory_Part_Num, I.Description, I.On_Hand_Stock,
COUNT (B.Part_Number) AS Back_Order_Count, SUM(B.Back_Order_Qty) as BO_Qty,
COUNT(O.Part_Number) AS Late_Deliveries_Count, SUM(O.Order_Qty) AS Late_Qty
FROM (tbl_Inventory_Master AS I
LEFT OUTER JOIN tbl_Customer_Back_Order AS B
ON I.Inventory_Part_Num = B.Part_Number)
LEFT OUTER tbl_On_Order AS O
ON I.Inventory_Part_Num = O.Part_Number
WHERE
I.Customer_Code = '274' AND
O.Due_Date < [ENTER TODAYS DATE IN FORMAT DD/MM/YYYY]
GROUP BY I.Inventory_Part_Num, I.Description, I.On_Hand_Stock
For example, for the part number 2022940 I should have 10 back order lines and an overdue quantity of 43. Instead, the query is returning 20 back order lines and an overdue quantity sum of 86.
From the on order table I have three orders totaling 144 pieces, instead the query is returning 960.
Can someone please advise, as this is driving me crazy?
You are joining along unrelated dimensions, so you need to aggregate before joining:
SELECT I.Inventory_Part_Num, I.Description, I.On_Hand_Stock,
B.Back_Order_Count, B.BO_Qty,
O.Late_Deliveries_Count, O.Late_Qty
FROM (tbl_Inventory_Master AS I LEFT OUTER JOIN
(SELECT B.Part_Number, COUNT(*) as Back_Order_Count,
SUM(B.Back_Order_Qty) as BO_Qty
FROM tbl_Customer_Back_Order AS B
GROUP BY B.Part_Number
) as B
ON I.Inventory_Part_Num = B.Part_Number
) LEFT JOIN
(SELECT O.Part_Number, COUNT(O.Part_Number) AS Late_Deliveries_Count,
SUM(O.Order_Qty) AS Late_Qty
FROM tbl_On_Order AS O
WHERE O.Due_Date < [ENTER TODAYS DATE IN FORMAT DD/MM/YYYY]
GROUP BY O.Part_Number
) as O
ON I.Inventory_Part_Num = O.Part_Number
WHERE I.Customer_Code = '274';
Notice the outer aggregation is no longer needed.

SQL query to report on what invoices have not been paid, ordered by invoice number

new to SQL and only been doing it for a week and a half. So I apologise now for the question being simple or appearing to be stupid.
I want to present a report on invoices that have not been paid by a given date, ordered by invoice number.
This is how I have displayed, the paid invoices but without the given date.. How do I display, the invoices that have not been paid by say 31-MAR-14.
SELECT INVOICE.INVOICE_NUMBER, INVOICE.INVOICE_DATE, PAYMENT.PAYMENT_NO, PAYMENT.INVOICE_NUMBER
FROM INVOICE, PAYMENT
WHERE INVOICE.INVOICE_NUMBER = PAYMENT.INVOICE_NUMBER
ORDER BY INVOICE.INVOICE_NUMBER;
SELECT PAYMENT.PAYMENT_NO
FROM INVOICE, PAYMENT
WHERE INVOICE.INVOICE_NUMBER = PAYMENT.INVOICE_NUMBER
AND INVOICE.INVOICE_DATE = 'AAAAMMJJ'
ORDER BY INVOICE.INVOICE_NUMBER;
Try something like this.
I have question. How do you say the invoice are not paid ?
You need to join the two tables together with a LEFT JOIN, then look to see where the payment date is > 31-MAR-14. Try something like this:
SELECT INVOICE.INVOICE_NUMBER, INVOICE.INVOICE_DATE, PAYMENT.PAYMENT_NO, PAYMENT.INVOICE_NUMBER
FROM INVOICE
LEFT JOIN PAYMENT ON INVOICE.INVOICE_NUMBER = PAYMENT.INVOICE_NUMBER
WHERE PAYMENT.Date_of_payment > '3/31/2014'
ORDER BY INVOICE.INVOICE_NUMBER;
This looks for all payments that were made after 3/31/2014. You may need to add another condition, that limits what invoices you're looking for.
To check payments that have not been made, look where any field in the PAYMENT table is null. SQL like this:
SELECT INVOICE.INVOICE_NUMBER, INVOICE.INVOICE_DATE, PAYMENT.PAYMENT_NO, PAYMENT.INVOICE_NUMBER
FROM INVOICE
LEFT JOIN PAYMENT ON INVOICE.INVOICE_NUMBER = PAYMENT.INVOICE_NUMBER
WHERE INVOICE.INVOICE_DATE = '3/31/2014'
AND PAYMENT.PAYMENT_NO IS NULL
ORDER BY INVOICE.INVOICE_NUMBER;
LEFT JOIN in this case will always return values for the INVOICE table, but may return NULL values in place of the PAYMENT if a payment has not been entered yet. Checking AND PAYMENT.PAYMENT_NO IS NULL will tell you that a payment has not been made yet.

SQL AVG in subselect

I want to get rates from a product (productId) that is in a specific category (fk_rate_category) and the overall average rates from all products in the category.
To be more specific: I need the data for a chart. One line in the chart represents the rate of a product(y-axis = rate ; x-axis = date_added) and the other line shows the average rates of all products.
I had the following approach:
SELECT id, productId, rate, fk_rate_category, date_added,
(SELECT AVG(rate) AS Expr1
FROM rates
WHERE (fk_rate_category = r.fk_rate_category)) AS avgRate
FROM rates AS r
WHERE (productId = #productId) AND (fk_rate_category = #fk_rate_category)
The problem is, that with my approach the avgRates value is the same in every record returned.
Any idea?
Firstly, always try to avoid using a correlated subquery when you can achieve the same result with a join, the optimiser will deal with it much better and you'll get the results faster.
I think the problem could be because you are not linking the dates of the data as well as FK_Rate_Cateogry, I'd imagine if this is for graphical purposes you would want the average by date:
SELECT r.ID,
r.ProductID,
r.Rate,
r.FK_Rate_Category,
r.Date_Added,
ar.avgRate
FROM Rates r
LEFT JOIN
( SELECT r.Date_Added,
r.FK_Rate_Category,
AVG(r.Rate) AS avgRate
FROM Rates r
GROUP BY r.FK_Rate_Category, r.Date_Added
) ar
ON ar.FK_Rate_Category = r.FK_Rate_Category
AND ar.Date_Added = r.Date_Added
WHERE r.ProductID = #ProductID
AND r.FK_Rate_Category = #FK_Rate_Category;
You got the set of records which have the specific id and rate_category. And avgRate is an average value from all records with the same rate_category - this set has the outer one as subset(see conditions of both queries). So all returned records have the same avgRate value.
So I see some holes in your logic line.

Handling negative values with sql

I have a data set that lists the date and quantity of future stock of products. Occasionally our demand outstrips our future supply and we wind up with a negative future quantity. I need to factor that future negative quantity into previous supply so we don't compound the problem by overselling our supply.
In the following data set, I need to prepare for demand on 10-19 by applying the negative quantity up the chain until i'm left with a positive quantity:
"ID","SKU","DATE","SEASON","QUANTITY"
"1","001","2012-06-22","S12","1656"
"2","001","2012-07-13","F12","1986"
"3","001","2012-07-27","F12","-283"
"4","001","2012-08-17","F12","2718"
"5","001","2012-08-31","F12","-4019"
"6","001","2012-09-14","F12","7212"
"7","001","2012-09-21","F12","782"
"8","001","2012-09-28","F12","2073"
"9","001","2012-10-12","F12","1842"
"10","001","2012-10-19","F12","-12159"
I need to get it to this:
"ID","SKU","DATE","SEASON","QUANTITY"
"1","001","2012-06-22","S12","1656"
"2","001","2012-07-13","F12","152"
I have looked at using a while loop as well as an outer apply but cannot seem to find a way to do this yet. Any help would be much appreciated. This would need to work for sql server 2008 R2.
Here's another example:
"1","002","2012-07-13","S12","1980"
"2","002","2012-08-10","F12","-306"
"3","002","2012-09-07","F12","826"
Would become:
"1","002","2012-07-13","S12","1674"
"3","002","2012-09-07","F12","826"
You don't seem to get a lot of answers - so here's something if you won't get the right 'how-to do it in pure SQL'. Ignore this solution if there's anything SQLish - it's just a defensive coding, not elegant.
If you want to get a sum of all data with same season why deleting duplicate records - just get it outside, run a foreach loop, sum all data with same season value, update table with the right values and delete unnecessary entries. Here's one of the ways to do it (pseudocode):
productsArray = SELECT * FROM products
processed = array (associative)
foreach product in productsArray:
if product[season] not in processed:
processed[season] = product[quantity]
UPDATE products SET quantity = processed[season] WHERE id = product[id]
else:
processed[season] = processed[season] + product[quantity]
DELETE FROM products WHERE id = product[id]
Here is a CROSS APPLY - tested
SELECT b.ID,SKU,b.DATE,SEASON,QUANTITY
FROM (
SELECT SKU,SEASON, SUM(QUANTITY) AS QUANTITY
FROM T1
GROUP BY SKU,SEASON
) a
CROSS APPLY (
SELECT TOP 1 b.ID,b.Date FROM T1 b
WHERE a.SKU = b.SKU AND a.SEASON = b.SEASON
ORDER BY b.ID ASC
) b
ORDER BY ID ASC