SQL: Show transactions since last zero balance - sql

I'm trying to display all of a customer's transactions since they last had a zero balance.
The current report I have displays transactions according to dates I input manually, using the following SQL:
SELECT rmledg.chgcode,
trandate,
nameid,
srccode,
rmledg.descrptn,
tranamt,
chkdesc,
posted,
rmbatchid,
namegroup,
NULL,
chgcode.class
FROM rmledg
LEFT JOIN chgcode
ON chgcode.chgcode=rmledg.chgcode
WHERE trandate>=qrydate{[BEGIN]}
AND trandate <=qrydate{[END]}
AND rmledg.namegroup='CELL{NAMEGROUP}'
The stuff in {brackets} are variables within the program.
I see a lot of tips around the net as to how to calculate the current balance, but not how to return all of the transactions since last zero balance.
This is for a Late Letter. We want to show everything that's happened since the person was last paid in full. I would appreciate any help.

Related

SQL: Find nth order for nth customer

I am quite new to SQL, have been learning for ~3 weeks, and have taken a liking to it. Hoping to polish up my skills before beginning to apply to Data Analyst roles.
I've been working with a dummy dvd-rental database and have found myself unable to solve a challenge given to me by a peer. The question was: "what is the most expensive rental for the 4th customer?"
We can see in picture, that based on the nth_customer column, Terrance Roush is the 4th ever customer (he's the 4th ever person to pay). But the issue is that the nth_customer column is actually reporting back the nth order and continues counting to infinity. So the next time Terrance shows up, the nth_customer column will not show '4' (which is what I was hoping to achieve).
Would appreciate any feedback on how to solve this. Thank you in advance.
If "the fourth customer" means the customer who did the fourth rental, you can break the problem down into two - finding that fourth customer, and finding their most expensive rental. Something like this:
SELECT *
FROM payment
WHERE customer_id = (
SELECT customer_id
FROM payment
ORDER BY payment_date
LIMIT 1 OFFSET 3
)
ORDER BY amount DESC
LIMIT 1;
Here I'm finding the ID of the fourth customer in the subquery, using a LIMIT & OFFSET to get just the one record I want. Then in the outer query I'm simply ordering all of that customer's records and taking the one with the biggest amount.

Rolling Balances with Allocated Transactions

I am needing to Calculate the start/end Balances by day for each Site/Department.
I have a source table call it “Source” that has the following fields:
Site
Department
Date
Full_Income
Income_To_Allocate
Payments_To_Allocate
There are 4 Sites (SiteA/SiteB/SiteC/SiteD), Sites B-D have only 1 department and Site A has 10 departments.
This table is “mostly” a daily summary. I say “mostly” as the daily detail from 2018 was lost and instead we just have the monthly summary inputted as one entry on the last day of the month. For 2018 there is only data going back to September. From 1/1/2019 the summary is actually daily.
Any Income in the Full_Income field will be given to that Site/Department at 100% value.
Any Income in the Income_To_Allocate field will be spread among all the Site/Departments using the below logic:
(
(Prior_Month_Site_Department_ Balance+ This_Month_Site_Department_Full_Income)
/
(Prior_Month_All_Department_Balance + This_Month_All_Department_Full_Income)
)
*
(This_Month_All_Department_Income_to_Allocate)
Any Payments in the Payments_to Allocate) field will be spread among all the Site/Departments using the below logic:
(
(Prior_Month_Site_Department_ Balance+ This_Month_Site_Department_Full_Income)
/
(Prior_Month_All_Department_Balance + This_Month_All_Department_Full_Income)
)
*
(This_Month_All_Department_Payments_to_Allocate)
The idea behind these pieces of logic is to spread the allocated pieces based on the % of business each Site/Department did when looking at the Full_Income data.
The Balance would be calculated with this logic:
Start Balance:
Prior day Ending Balance
Ending Balance:
Prior day Ending Balance + (Site_Department_Full_Income) + (Site_Department_Allocated_Income)- (SiteDepartment_Allocated_Income)
I have tried to do things using the lag function to grab the prior info that I am needing for these calculations. I always get real close but I always wind up stuck on the fact the Ending Balance is calculated using the post spread values for the allocated income and reseeds while the calculation for the spread is using the prior month balance info. This ends up being almost circular logic but with a finite start point. I am at a loss for how to make this work.
I am using SQL Server 2012. Let me know if you need any more details.

Query to find average stock ... with a twist

We are trying to calculate average stock from a movements table in a single sql sentence.
As far as we are, no problem with what we thought was a standard approach, instead of adding up the daily stock and divide by the number of days, as we don’t have daily stock, we simply add (movements*remaining days) :
select sum(quantity*(END_DATE-move_date))/(END_DATE-START_DATE)
from move_table
where move_date<=END_DATE
This is a simplified example, in real life we already take care of the initial stock at the starting date. Let’s say there are no movements prior to start_date.
Quantity sign depends on move type (sale, purchase, inventory, etc).
Of course this is done grouping by product, warehouse, ... but you get the idea.
It works as expected and the calculus is fine.
But (there is always a “but”), our customer doesn’t like accounting days when there is no stock (all stock sold out). So, he doesnt like
Sum of (daily_stock) / number_of_days (which is what we calculate using a diferent math)
Instead, he would like
Sum of (daily stock) / number_of_days_in_which_stock_is_not_zero
For sure we can do this in any programming language without much effort, but I was wondering how to do it using plain sql ... and wasn’t able to come up with a solution.
Any suggestion?
Consider creating a new table called something like Stock_EndOfDay_History that has the following columns.
stock#
date
stock_count_eod
This table would get a new row for each stock item at the start of a new day for the prior day. Rows could then be purged from this table once the applicable date value went outside the date window of interest.
To get the "number_of_days_in_which_stock_is_not_zero", use this.
SELECT COUNT(*) AS 'Not_Zero_Stock_Days' FROM Stock_EndOfDay_History
WHERE stock# = <stock#_value>
AND <date_window_clause>
Other approaches might attempt to just add a new column to the existing stock table to maintain a cumulative sum of the " number_of_days_in_which_stock_is_not_zero". But inevitably, questions will be asked as to how did the non-zero stock days count get calculated? Using this new table approach will address those questions better than the new column approach.

Filter PowerPivot based on multiple Date Criteria

I am trying to apply some Time Intelligence functions in my PowerPivot workbook concerning projects and money received for them. I have three relevant tables; Matters, Payments, and a Date Table.
Each matter has a creationDate, and a closureDate(from a linked table). Likewise, each payment has a date. I have reporting set up decently, but am now trying to use Time intelligence to filter this a bit more clearly.
How can I set a PowerPivot Pivot Table up so that the only Matters which show are those which existed within the period selected. e.g. If I select a slicer for 2014, I don't want to show a matter created in 2015, or one which was closed in 2013. The matter should have been active during the period specified.
Is this possible?
You want to show all the matters EXCEPT those where the CreationDate is after the upper limit of the date range you are looking at or the ClosureDate is before the lower limit of the date range you are looking at.
Assuming you have a data structure like this, where the left-hand table is the Matters and the right-hand one is the Payments:
If you have a calculated field called [Total Payments] that just adds up all the payments in the Payments table, a formula similar to this would work:-
[Payment in Range]:=IF(OR(MIN(Matters[Creation Date])>MAX('Reporting Dates'[Date]),MAX(Matters[Closure Date])<MIN('Reporting Dates'[Date])),BLANK(),[Total Payments])
Here is the result with one month selected in the timeline:
Or with one year selected in the year slicer:
NOTE: in my example, I have used a disconnected date table.
Also, you will see that the Grand Total adds up all the payments because it takes the lowest of all the creation dates and the highest of all the closure dates to determine whether to show a total payment value. If it is important that the Grand Total shows correctly, then an additional measure is required:
[Fixed Totals Payment in Range]:=IF(COUNTROWS(VALUES(Matters[Matter]))=1,[Payment in Range],SUMX(VALUES(Matters[Matter]),[Payment in Range]))
Replace the [Payment in Range] in your pivot table with this new measure and the totals will show correctly, however, this will only work if Matters[Matter] is used as one of the fields in the pivot table.
Use filters & the calculate function.
So, if you're Summing payments, it would look like.....
Payments 2014:= CALCULATE( SUM([Payments]), DateTable[Year]=2014)
The Sum function takes the entirety of payments & the filter function will only capture payments w/in 2014, based on the data connected to your date table.

Iif statement and select subquery inside update query Access

I am working on a database to help me keep track of employee leave and attendance records. I created an Employees table, with the list of employees and the yearly leave balances that roll forward from the previous year. I then made a Leave Records table that lists the leave accrued and used for each pay period. I can use a formula to calculate the leave balance forward automatically once the leave balance forward for that pay period has been entered. What I'm having trouble with is getting the database to automatically calculate the leave balance that rolls forward. The balance will change for each pay period, however what the value needs to be is the leave balance total for the same employee in the previous pay period.
I have the following SQL in a select query and it works:
A/L Bal Fwd: IIf([Leave Records].[Pay Period]=1,[Employees].[Yearly A/L Bal Fwd],(SELECT [Leave Records].[A/L Balance to Date]
FROM [Leave Records] AS Dupe
WHERE Dupe.Employee = [Leave Records].Employee
AND Dupe.[Pay Period] = [Leave Records].[Pay Period]-1)) AS [A/L Bal Fwd]
FROM Employees INNER JOIN [Leave Records] ON Employees.ID = [Leave Records].Employee;
The issue now is that any pay period beyond #1 it will not return a value unless data has been entered into the [Leave Records] table. My goal is to find a way to have access automatically calculate the value in [Leave Records].[A/L Bal Fwd] to save time from having to calculate that same field every pay period for 56 employees. I tried running an update query with the Iif statement above, but it only returned blank values. I'm trying to avoid creating temporary tables and having too many queries to run to have it update each pay period as much as possible. The fewer steps I have to take for these values to update and be correct each pay period, the better.