Conditioned based Running total - sql

I am rewriting this Post!
This is my Query
SELECT ITEMNUM,
STORELOC,
TRANSDATE,
ACTUALDATE,
CONDITIONCODE,
ISSUETYPE,
QUANTITY,
CURBAL,
'' AS Balnce_In_Condition_02,
ENTERBY,
MEMO,
DOCNUM
FROM MATUSETRANS
WHERE ITEMNUM = 'Z95-04-BHH811550'
AND STORELOC ='04'
AND TRANSDATE >'01-JAN-19'
ORDER BY TRANSDATE DESC;
and it is my result
I need running Balance_In_Condition_02 which I write separately in image. Basically my need is to create a Inventory report of Items which is issue from CONDITIONCODE 01 while the same item was present in CONDITIONCODE 02. Items are frequently ISSUE and RETURN. Hope you can understand my question

At first sum quantity conditionally, only for rows with conditioncode = '02', like in my inner query. Then use analytic lead() to fill values for the rest of rows.
select itemnum, storeloc, transdate, quantity, conditioncode,
nvl(bal02, lead(bal02) ignore nulls
over (partition by itemnum order by transdate desc)) balance02
from (
select itemnum, storeloc, transdate, quantity, conditioncode,
case conditioncode when '02' then sum(quantity)
over (partition by itemnum order by transdate desc) end bal02
from matusetrans mtu
where itemnum = 'Z95-04-B806073A' and storeloc = '04')
order by transdate desc;
dbfiddle
I am not sure if you are summing all quantities or only 02 rows, because in your example these sums are equal. In this second case instead of sum(quantity) use:
sum(case conditioncode when '02' then quantity end) over (...

Related

PARTITION BY first use of a particular product

I'm trying to produce a table that lists the month, account and product name from our billing database. However, I also want to understand (for subsequent cohort analysis) what the earliest use is of "Product A" for each line item too. I was hoping I could do the following:
SELECT
Month,
AccountID,
ProductName,
SUM(NetRevenue) AS NetRevenue,
MIN(Month) OVER(PARTITION BY AccountID, 'Product A') AS EarliestUse
FROM
<<my-billing-table>>
WHERE
NetRevenue > 0
AND AccountID IN (
SELECT DISTINCT AccountID
FROM <<my-billing-table>>
WHERE ProductName = 'Product A' AND NetRevenue > 0
)
GROUP BY 1,2,3
...but it seems that just using "Product A" within the OVER clause does not have the desired effect (it seems to just return the first month for AccountID).
While the syntax is fine and the query runs, I'm obviously missing something regarding PARTITIONing the OVER clause. Any help much appreciated!
I think you want conditional aggregation along with a window function:
SELECT Month, AccountID, ProductName,
SUM(NetRevenue) AS NetRevenue,
MIN(MIN(CASE WHEN ProductName = 'Product A' THEN month END)) OVER (PARTITION BY AccountID) AS EarliestUse
FROM <<my-billing-table>>
WHERE NetRevenue > 0 AND
AccountID IN (SELECT AccountID
FROM <<my-billing-table>>
WHERE ProductName = 'Product A' AND NetRevenue > 0
)
GROUP BY 1,2,3;
The key expression here is an aggregation function nestled inside a window function. The aggregation function is MIN(CASE WHEN ProductName = 'Product A' THEN month END). This calculates the earliest month for the specified product on each row. This could be a column in the result set, and you would see the minimum value on the product row.
The window function then "spreads" this value over all rows for a given AccountID.
you are using a constant in partition it will not impact in your result, should use the column ProductName in partition to get the earliest use of the product
SELECT
Month,
AccountID,
ProductName,
SUM(NetRevenue) AS NetRevenue,
MIN(Month) OVER(PARTITION BY AccountID, ProductName) AS EarliestUse
FROM
<<my-billing-table>>
WHERE
NetRevenue > 0
AND AccountID IN (
SELECT DISTINCT AccountID
FROM <<my-billing-table>>
WHERE ProductName = 'Product A' AND NetRevenue > 0
)
GROUP BY 1,2,3

T-SQL GROUP BY: Eliminate multiple occurrences

How can I prevent multiple identical price rows in the below query due to different date values? I only need to show the first occurrence of a record where price is different than the previous ones but skip until there is another change to the price field.
SELECT STOCKID, PRICE, TRANSTYPENAME, TRANSDATE
FROM VE_STOCKTRANS
WHERE STOCKID = 6000 AND TANSTYPE IN (3500,3553)
GROUP BY PRICE, STOCKID, TRANSTYPENAME, TRANSDATE
i.e. I need to omit the multiple 35.83333333 rows and only take the first occurrence of it (24/4/2018)
Image reply to Gordon's Answer:
You can get first TRANSDATE like that:
SELECT STOCKID, PRICE, TRANSTYPENAME, min(TRANSDATE)
FROM VE_STOCKTRANS
WHERE STOCKID = 6000 AND TRANSTYPE IN (3500,3553)
GROUP BY PRICE, STOCKID, TRANSTYPENAME
SELECT STOCKID, DISTINCT(PRICE), TRANSTYPENAME, TRANSDATE)
FROM VE_STOCKTRANS
WHERE STOCKID = 6000 AND TANSTYPE IN (3500,3553)
GROUP BY PRICE, STOCKID, TRANSTYPENAME, TRANSDATE
This might helps..
Use LAG() to see if the price changed:
SELECT STOCKID, PRICE, TRANSTYPENAME, TRANSDATE
FROM (SELECT st.*,
LAG(st.price) OVER (PARTITION BY stockId ORDER BY transdate) as prev_price
FROM VE_STOCKTRANS st
WHERE STOCKID = 6000 AND TANSTYPE IN (3500, 3553)
) st
WHERE prev_price IS NULL OR prev_price <> price;
EDIT:
If you just want a list of the first time that each price is seen (which is quite different from changes in prices, as you have noted and described in the question), use row_number():
SELECT STOCKID, PRICE, TRANSTYPENAME, TRANSDATE
FROM (SELECT st.*,
ROW_NUMBER() OVER (PARTITION BY st.stockId, st.price ORDER BY st.transdate) as seqnum
FROM VE_STOCKTRANS st
WHERE STOCKID = 6000 AND TANSTYPE IN (3500, 3553)
) st
WHERE seqnum = 1;

How to get the last sold price in SQL

I am working on a query that will show me basic item information as well as the total qty shipped (for all orders),last date that the item was sold and the price it was sold at. I cant figure out how to get the last sold price. This is what I have so far,
SELECT
item_id
,item_desc
,sum(qty_shipped) AS 'Total Qty Shipped'
,count(item_id) AS 'No of times Shipped'
,max(invoice_date) AS 'Last Invoice_date'
,unit_price AS 'Last Price'
FROM sales_history_report
WHERE
item_id = '1234'
AND year_for_period >= '2017'
AND sales_location_id like '10'
GROUP BY
item_id
,item_desc
,unit_price
with this query I am getting all of the lines that this item is on. It looks like this right now,
Item_id,Item_desc,Total_QTY_shipped,no_of_times_shipped,Last_Invoice_date,Last_price
1234,Item 1234,4,1,2014-10-15,2.47
1234,Item 1234,6,1,2014-09-20,2.519
But I am looking for
Item_id,Item_desc,Total_QTY_shipped,no_of_times_shipped,Last_Invoice_date,Last_price
1234,Item 1234,10,2,2014-10-15,2.47
Any help would be appreciated.
If I understand correctly, you can use conditional aggregation:
select item_id, item_desc,
sum(qty_shipped) as [Total Qty Shipped],
count(item_id) as [No of times Shipped],
max(invoice_date) as Max_Date,
max(case when seqnum = 1 then unit_price end) as [Last Price],
from (select shr.*,
row_number() over (partition by item_id order by invoice_date desc) as seqnum
from sales_history_report shr
) shr
where item_id = 1234 and
year_for_period >= 2017 and
sales_location_id like '10'
group by item_id, item_desc;
Comments:
Do not use single quotes for column aliases. Only use single quotes for string and date constants.
The columns in the GROUP BY define the rows in the result set. I don't think you want unit_price in it.
Do not use single quotes for numeric constants. I assume item_id an the year are numeric.

How can I add cumulative sum column?

I use SqlExpress
Following is the query using which I get the attached result.
SELECT ReceiptId, Date, Amount, Fine, [Transaction]
FROM (
SELECT ReceiptId, Date, Amount, 'DR' AS [Transaction]
FROM ReceiptCRDR
WHERE (Amount > 0)
UNION ALL
SELECT ReceiptId, Date, Amount, 'CR' AS [Transaction]
FROM ReceiptCR
WHERE (Amount > 0)
UNION ALL
SELECT strInvoiceNo AS ReceiptId, CONVERT(datetime, dtInvoiceDt, 103) AS Date, floatTotal AS Amount, 'DR' AS [Transaction]
FROM tblSellDetails
) AS t
ORDER BY Date
Result
want a new column which would show balance amount.
For example. 1 Row should show -2500, 2nd should -3900, 3rd should -700 and so on.
basically, it requires previous row' Account column's data and carry out calculation based on transaction type.
Sample Result
Well, that looks like SQL-Server , if you are using 2012+ , then use SUM() OVER() :
SELECT t.*,
SUM(CASE WHEN t.transactionType = 'DR'
THEN t.amount*-1
ELSE t.amount END)
OVER(PARTITION BY t.date ORDER BY t.receiptId,t.TransactionType DESC) as Cumulative_Col
FROM (YourQuery Here) t
This will SUM the value when its CR and the value*-1 when its DR
Right now I grouped by date, meaning each day will recalculate this column, if you want it for all time, replace the OVER() with this:
OVER(ORDER BY t.date,t.receiptId,t.TransactionType DESC) as Cumulative_Col
Also, I didn't understand why in the same date, for the same ReceiptId DR is calculated before CR , I've add it to the order by but if thats not what you want then explain the logic better.

Working out total from sub total and amount

I have a table with purchased orders data.
Each row contails the amount of certain item purchased, cost per item and the order number group. Each different item purchased is a new row with same order number.
I basically want to return the total cost for that order. I have tried the following but am getting nowhere:
SELECT order_number, SUM( sub_total ) AS `total`
FROM
SELECT order_number, SUM( SUM( amount ) * SUM( cost_per_item ) ) AS `sub_total`
FROM `ecom_orders`
WHERE member_id = '4'
GROUP BY order_number
ORDER BY purchase_date DESC
Pretty much any SQL-92 compliant RDBMS will take this:
SELECT
order_number
,SUM(amount * cost_per_item) AS total
,purchase_date
FROM
ecom_orders
WHERE member_id = '4'
GROUP BY order_number,purchase_date
ORDER BY purchase_date DESC