Access get value from previous record - ms-access

I have an Access query with the following
GL_A.Account,
GL_P.FiscalYear,
GL_P.FiscalPeriod,
GL_P.BeginningBalance,
GL_P.DebitAmount,
GL_P.CreditAmount,
[BeginningBalance]+([DebitAmount]-[CreditAmount]) AS EndingBalance
The problem is that BeginningBalance only has values for January (FiscalPeriod 1).
I need to have a new field ActualBeginngBal which comes from the previous month EndingBalance (Except January)
Note: there are many account #'s but each account only has 1 record per FiscalPeriod/FiscalYear
Your help would be greatly appreciated,
Thank you

See if this helps. Put a 2nd copy of the table in the query, joined to the 1st copy on Account and FiscalYear but not on FiscalPeriod. Then the ActualBeginningBalance can be calculated from the 2nd copy of the table with a constraint to select only FiscalPeriod < the FiscalPeriod from the 1st table. Note - you may get a null results for January, which you may need to convert to a 0.
OK, it's a bit more complicated - I did end up using a subquery similar to the other response, but calculated the EB instead of trying to pull it from the table
SELECT Ledger.Account, Ledger.FiscalYear, Ledger.FiscalPeriod,
[BeginningBalance]+
IIf([FiscalPeriod]<>"01",
(select sum(T.BeginningBalance+T.DebitAmount-T.CreditAmount)
from Ledger T
where T.account=Ledger.account and T.FiscalYear=Ledger.FiscalYear and T.FiscalPeriod<Ledger.FiscalPeriod)
,0)
AS ActualBeginningBalance,
Ledger.DebitAmount AS DebitAmount,
Ledger.CreditAmount AS CreditAmount,
[ActualBeginningBalance]+[DebitAmount]-[CreditAmount] AS EndingBalance
FROM Ledger;

This SQL does the job and returns the table below (with my test data):
SELECT T1.Account
, T1.FiscalYear
, T1.FiscalPeriod
, T1.ActualBeginngBal
, (
SELECT TOP 1 T2.EndingBalance
FROM Table1 T2
WHERE CLNG(T2.FiscalYear & Format(T2.FiscalPeriod,"00")) <
CLNG(T1.FiscalYear & Format(T1.FiscalPeriod,"00")) AND
T2.Account = T1.Account
ORDER BY CLNG(T2.FiscalYear & Format(T2.FiscalPeriod,"00")) DESC
) AS BeginningBalance
, T1.EndingBalance
FROM Table1 T1

IT WOULD BE BETTER IF YOU USE BeginningBalance in primary table. Because it is only one record belong to one account. it is one to one relationship.

How about moving to the previous record, grabbing the value, and returning to the original record.
For example:
Private Sub txtXYZ1_AfterUpdate()
Dim tmpXYZ As Single
DoCmd.GoToRecord , , acPrevious
tmpXYZ = txtXYZ1
DoCmd.GoToRecord , , acNext
txtPriorXYZ = tmpXYZ
txtXYZChange = txtXYZ1 - txtPriorXYZ
End Sub

Related

how to know the source table from a complex sql query

PFB the query in which I want know the actual table where I can find these (pin_ein,engineer_pin,transaction_date,EFFECTIVE_WEEK )....
select count(1),pin_ein,engineer_pin,transaction_date,EFFECTIVE_WEEK from
(SELECT vw1.pin_ein, vw1.engineer_pin,
vw1.transaction_date, vw1.effective_week,
vw1.stores_tools_cost,
(vw1.stores_total_cost - vw1.stores_tools_cost
) stores_total_cost_excl_tools,
vw1.item_count, vw1.stores_visit_count,
CASE
WHEN vw1.stores_total_cost <
5
THEN vw1.stores_visit_count
END stores_low_cost_visit_count,
vw1.actual_ouc ouc, er.eng_name engineer_name,
CASE
WHEN c.home_parked IS NOT NULL
THEN c.home_parked
ELSE 'N'
END home_parker,
CASE
WHEN c.home_parked IS NOT NULL
THEN c.commute_time
ELSE -99
END commute_time,
vw1.stores_com_cost ---v9.3---
FROM (SELECT pin_ein, engineer_pin, actual_ouc,
transaction_date, effective_week,
NVL
(SUM
(CASE
WHEN ( cow LIKE '%TOOL%'
OR cow LIKE
'%TOOLE%'
)
THEN transaction_value
END
),
0
) stores_tools_cost,
SUM
(transaction_value
) stores_total_cost,
SUM (transaction_quantity)
item_count,
COUNT
(DISTINCT sta_code
) stores_visit_count,
NVL
(SUM
(CASE
WHEN cow in (SELECT cow FROM orbit_odw.stores_cow_ref)
THEN transaction_value
END
),
0
) stores_com_cost ---v9.3---
FROM orbit_odw.stores_transaction_dtls
WHERE effective_week BETWEEN 201543
AND 201610
/***Ver 6.0---last 13 weeks data to be considered***/
AND transaction_date
BETWEEN to_date('19-10-2015','dd-mm-yyyy')
AND to_date('06-03-2016','dd-mm-yyyy')
/***Ver 6.0---last 13 weeks data to be considered***/
GROUP BY pin_ein,
engineer_pin,
actual_ouc,
transaction_date,
effective_week) vw1,
(SELECT *
FROM orbit_odw.dim_wms_rmdm
WHERE current_status = 1) er,
(SELECT engineer_ein, commute_time,
home_parked
FROM orbit_odw.eng_parking_at_home_dtls
WHERE rec_end_date > SYSDATE
AND home_parked = 'Y') c
WHERE TO_CHAR (vw1.pin_ein) = er.ein
AND vw1.pin_ein = c.engineer_ein(+)) group by pin_ein,engineer_pin,transaction_date,EFFECTIVE_WEEK having count(1)>1;
Please help..
thanks in advance
Basically if i understand your problem correctly. You need to understand from where your outer SELECT is fetching data. So there is a simple rule set used to get these data. Steps are as follows.
Check the column output i.e in your case it's
pin_ein,engineer_pin,transaction_date,EFFECTIVE_WEEK
Check the inline view or table from which your outer query is
fetching the data. In your case its the only inline view you have
used --> So bit easy to identify :P
Now to identify how your inline view VW1 is populating data. In your
case table orbit_odw.stores_transaction_dtls is used to populate the
required fields.
Hope this much information is required. Also for simple queries you can always go to ALL_TAB_COLUMNS system tables to identify a table's column easily.

filed showing null value when joining table

below is my query
select C.cName,DATE_FORMAT(CT.dTransDate,'%d-%M-%Y') as dTransDate,
(c.nOpBalance+IFNULL(CT.nAmount,0)) AS DrAMount,IFNULL(CTR.nAmount,0) AS
CrAMount,((c.nOpBalance+IFNULL(CT.nAmount,0))-IFNULL(CTR.nAmount,0)) AS
Balance,CT.cTransRefType,CT.cRemarks,cinfo.cCompanyName,cinfo.caddress1,cinfo.cP
honeOffice,cinfo.cMobileNo,cinfo.cEmailID,cinfo.cWebsite from Customer
C LEFT JOIN Client_Transaction CT ON CT.nClientPk = C.nCustomerPk AND
CT.cTransRefType='PAYMENT' AND CT.cClientType='CUSTOMER' AND CT.dTransDate
between '' AND '' LEFT JOIN Client_Transaction CTR ON CTR.nClientPk =
C.nCustomerPk AND CTR.cTransRefType='RECEIPT' AND
CTR.cClientType='CUSTOMER' AND CTR.dTransDate between '2015-05-01' AND
'2015-05-29' LEFT JOIN companyinfo cinfo ON cinfo.cCompanyName like
'%Fal%' Where C.nCustomerPk = 4 Order By dTransDate
it's showing all value but dTransDate ,cTransRefType,cRemarks, showing null.
One obvious thing jumps out at us:
CT.dTransDate BETWEEN '' AND ''
^^ ^^
Another thing that jumps out at us is that there's a semi-Cartesian join between rows from CT and rows from CTR. If 5 rows are returned from CT for a given customer, and 5 rows are returned from CTR, that's going to produce a total of 5*5 = 25 rows. That just doesn't seem like a resultset that you'd really want returned.
Also, if more than one row is returned from cinfo, that's also going to cause another semi-Cartesian join. If there's two rows returned from cinfo, the total number or rows in the resultset will be doubled. It's valid to do that in SQL, but this is an unusual pattern.
The calculation of the balance is also very strange. For each row, the nAmount is added/subtracted from opening balance. On the next row, the same thing, on the original opening balance. There's nothing invalid SQL-wise with doing that, but the result being returned just seems bizarre. (It seems much more likely that you'd want to show a running balance, with each transaction.)
Another thing that jumps out at us is that you are ordering the rows by a string representation of a DATE, with the day as the leading portion. (As long as all the rows have date values in the same year and month, that will probably work, but it just seems bizarre that we wouldn't sort on the DATE value, or a canonical string representation.
I strongly suspect that you want to run a query that's more like this. (This doesn't do a "running balance" calculation. It does return the 'PAYMENT' and 'RECEIPT' rows as individual rows, without producing a semi-Cartesian result.
SELECT c.cName
, DATE_FORMAT(t.dTransDate,'%d-%M-%Y') AS dTransDate
, C.nOpBalance
, IF(t.cTransRefType='PAYMENT',IFNULL(t.nAmount,0),0) AS DrAMount
, IF(t.cTransRefType='RECEIPT',IFNULL(t.nAmount,0),0) AS CrAMount
, t.cTransRefType
, t.cRemarks
, ci.*
FROM Customer c
LEFT
JOIN Client_Transaction t
ON t.nClientPk = c.nCustomerPk
AND t.cClientType = 'CUSTOMER'
AND t.dTransDate >= '2015-05-01'
AND t.dTransDate <= '2015-05-29'
AND t.cTransRefType IN ('PAYMENT','RECEIPT')
CROSS
JOIN ( SELECT cinfo.cCompanyName
, cinfo.caddress1
, cinfo.cPhoneOffice
, cinfo.cMobileNo
, cinfo.cEmailID
, cinfo.cWebsite
FROM companyinfo cinfo
WHERE cinfo.cCompanyName LIKE '%Fal%'
ORDER BY cinfo.cCompanyName
LIMIT 1
) ci
WHERE c.nCustomerPk = 4
ORDER BY t.dTransDate, t.cTransRefTpye, t.id

How to do this query against MySQL database table?

I was given a task to show the CPU usage trend as part of a building process which also do regression test.
Each individual test case run has a record in the table RegrCaseResult. The RegrCaseResult table looks something like this:
id projectName ProjectType returnCode startTime endTime totalMetrics
1 'first' 'someType' 16 'someTime' 'someOtherTime' 222
The RegrCaseResult.totalMetrics is a special key which links to another table called ThreadMetrics through ThreadMetrics.id.
Here is how ThreadMetrics will look like:
id componentType componentName cpuTime linkId
1 'Job Totals' 'Job Totals' 'totalTime' 34223
2 'parser1' 'parser1' 'time1' null
3 'parser2' 'generator1' 'time2' null
4 'generator1' 'generator1' 'time3' null
------------------------------------------------------
5 'Job Totals' 'Jot Totals' 'totalTime' 9899
...
The rows with the compnentName 'Job Totals' is what the totalMetrics from RegrCaseResult table will link to and the 'totalTime' is what I am really want to get given a certain projectType. The 'Job Totals' is actually a summation of the other records - in the above example, the summation of time1 through time3. The linkId at the end of table ThreadMetrics can link back to RegrCaseResult.id.
The requirements also states I should have a way to enforce the condition which only includes those projects which have a consistent return code during certain period. That's where my initial question comes from as follows:
I created the following simple table to show what I am trying to achieve:
id projectName returnCode
1 'first' 16
2 'second' 16
3 'third' 8
4 'first' 16
5 'second' 8
6 'first' 16
Basically I want to get all the projects which have a consistent returnCode no matter what the returnCode values are. In the above sample, I should only get one project which is "first". I think this would be simple but I am bad when it comes to database. Any help would be great.
I tried my best to make it clear. Hope I have achieved my goal.
Here is an easy way:
select projectname
from table t
group by projectname
having min(returncode) = max(returncode);
If the min() and max() values are the same, then all the values are the same (unless you have NULL values).
EDIT:
To keep 'third' out, you need some other rule, such as having more than one return code. So, you can do this:
select projectname
from table t
group by projectname
having min(returncode) = max(returncode) and count(*) > 1;
select projectName from projects
group by projectName having count(distinct(returnCode)) = 1)
This would also return projects which has only one entry.
How do you want to handle them?
Working example: http://www.sqlfiddle.com/#!2/e7338/8
This should do it:
SELECT COUNT(ProjectName) AS numCount, ProjectName FROM (
SELECT ProjectName FROM Foo
GROUP BY ProjectName, ReturnCode
) AS Inside
GROUP BY Inside.ProjectName
HAVING numCount = 1
This groups all the ProjectNames by their names and return codes, then selects those that only have a single return code listed.
SQLFiddle Link: http://sqlfiddle.com/#!2/c52b6/11/0
You can try something like this with Not Exists:
Select Distinct ProjectName
From Table A
Where Not Exists
(
Select 1
From Table B
Where B.ProjectName = A.ProjectName
And B.ReturnCode <> A.ReturnCode
)
I'm not sure exactly what you're selecting, so you can change the Select statement to what you need.

MS Access 2007/2010: Need to set Date field based on most recent of 5 other Date fields

I seem to have a problem I haven't encountered before within the same record. I need to set a Date field value based on the most recent date of 5 other Date fields. I would like to do this at the query level so that I can assign the most recent date and store it in a field, but I'm not sure if it's possible. If I have to do it within a Form, then I'm not sure how to write out the Case statement. Any help is appreciated!
What I'm trying to do now is write an expression that pretty much goes as follows:
ESA Exp Date: IIf([1-Record Search Date]>[2-Site Reconnaissance Date] And [1-Record Search Date]>[3-Owner Interview Date] And [1-Record Search Date]>[4-Lien/AUL Search Date] And [1-Record Search Date]>[5-User Questionnaire Date],[1-Record Search Date],IIf([2-Site Reconnaissance Date]>[1-Record Search Date]
And so on... However, expressions have a limit of characters, and so someone said in an unrelated question to write a function. I'm not sure how that would work in my case though.
Thanks again
Rob
If changing your table structure isn't an option then you can use a function like the one created by Allen Browne http://allenbrowne.com/func-09.html, there are fuller instructions on the webpage.
Call it in a query as: (may I suggest not putting spaces in whenever not required, will help further down the line in VBA)
ESAExpDate: MaxOfList([1-Record Search Date],_
[2-Site Reconnaissance Date],[3-Owner Interview Date],[4-Lien/AUL Search Date], _
[5-User Questionnaire Date])
I have pasted below in case the link dies.
Function MaxOfList(ParamArray varValues()) As Variant
Dim i As Integer 'Loop controller.
Dim varMax As Variant 'Largest value found so far.
varMax = Null 'Initialize to null
For i = LBound(varValues) To UBound(varValues)
If IsNumeric(varValues(i)) Or IsDate(varValues(i)) Then
If varMax >= varValues(i) Then
'do nothing
Else
varMax = varValues(i)
End If
End If
Next
MaxOfList = varMax
End Function
The reason this seems so difficult is because your table structure is not optimal for relational querying. Let's say your current table (date_values) has the columns d1 to d5, all dates. You need to normalise the table like so (note that this doesn't change your actual table, it just 'repackages' it in memory into an easier-to-query form):
select entity_id, 'type 1' as date_type, d1 as date_value
from date_values
where d1 is not null
union all
select entity_id, 'type 2' as date_type, d2 as date_value
from date_values
where d2 is not null
union all
select entity_id, 'type 3' as date_type, d3 as date_value
from date_values
where d3 is not null
union all
select entity_id, 'type 4' as date_type, d4 as date_value
from date_values
where d4 is not null
union all
select entity_id, 'type 5' as date_type, d5 as date_value
from date_values
where d5 is not null
Note that entity_id is any field which uniquely identifies a row in your table. Once you have data in a normalised form, querying is easy:*
update date_values as d
inner join (
select ssq.entity_id, max(ssq.date_value) as max_date
from (
... the query I show above ...
) as ssq
group by ssq.entity_id
) as sq
on d.entity_id = sq.entity_id
set d.[ESA Exp Date] = sq.max_date
where entity_id = [... the entity you wish to update ...]
The last clause above, the where clause, restricts the modification to a single row you can specify. You can enter it manually when prompted by Access or you can have it refer to a field in a form. There are many options.
* OK, easi_er_.

MDX Help: - Comparing Values in Two Max Time Periods within a larger Set of Time Periods to Populate an Indicator

I'm brand new to MDX and need some help. In SSRS I have a dataset that pulls from an SSAS cube. The dataset always contains six months of data. What I need to be able to do is to compare a value for the max(timeID) with a value for the second max(timeID) and if the value for the max(timeID) > value for the second max(timeID) than the arrow goes up in the indicator, etc...
So for the dataset below I would subtract 20130201's Value which is 8 from
20130301's Value which is 10. The result would be a positive number and the indicator would be an upward pointing green arrow. If it was 0 it would be straight and if negative the arrow would be red and point down. I understand how to deal with the indicator - that's not an issue. It's the MDX I need help with.
20130201 8
20130301 10
20121201 4
I can write it in SQL and it would look like this.
Select Item, case when sum(Time1ContentCount) > sum(Time2ContentCount) then 3 when sum(Time1ContentCount) = sum(Time2ContentCount) then 2 when sum(Time1ContentCount) sum(Time2ContentCount) then 1 end as Indicator, sum(Time1ContentCount) as Time1Count, sum(Time2ContentCount) as Time2Count from (Select timeID, dc.Item, Case when timeID = (Select max(timeID) from FactUsage) then count(fu.Contentid) else 0 END as Time1ContentCount, Case when timeID = (Select max(timeID) from FactUsage where timeID <>(Select max(timeID) from FactUsage)) then count(fu.Contentid) else 0 END as Time2ContentCount from factUsage fu INNER JOIN dimContent dC on dc.ContentID = fu.ContentID WHERE TimeID in (Select distinct top 6 timeid from factUsage order by timeID desc) Group by timeID, Item) a group by Item
Thanks so much for your help!
Edit:
I changed the statement to read as follows for the indicator.
WITH Member MEASURES.Indicator AS (
IIF(( [Measures].[Activity], [Time].[Time ID].LastChild ) >
( [Measures].[Activity], [Time].[Time ID].LastChild.PrevMember),3,
(IIF(([Measures].[Activity], [Time].[Time ID].LastChild ) =
([Measures].[Activity], [Time].[Time ID].LastChild.PrevMember), 2,1))))
SELECT {Measures.Indicator} on 0
FROM [DW]
It works when I run it as a query against the cube in SSMS but I tried to put it in the indicator and that doesn't work. Just adding the IIF statement doesn't work either. When I tried to add it into the query or the cube itself so I could just pull from there it errors out with an out of memory error.
I don't know how much you can edit in the MDX expression - or in your report builder, but to get the difference between two values in a series, you can create a measure (in your report) that is the difference between the CurrentMember and PrevMember. Since the time series (timeid) is sorted by the key, it will always be in the right order (or your schema and architecture needs a rework)
So basically, you can do :
WITH
MEMBER MEASURES.GrowthTime AS (
( [Measures].[Value], [TimeID].CurrentMember ) -
( [Measures].[Value], [TimeID].PrevMember )
)
MEMBER MEASURES.GrowthRatio AS (
( [Measures].[Value], [TimeID].CurrentMember ) /
( [Measures].[Value], [TimeID].PrevMember )
)
SELECT { Measures.Value, Measures.GrowthTime, Measures.GrowthRatio } on 0,
[TimeID].CHILDREN on 1
FROM Cube
This is pseudo as i don't know your cube structure. For TimeID you would want it like [DimensionName].[AttributeName].CurrentMember and PrevMember