MS Access SQL updating in sequence - sql

I have a table that provides a point-in-time snapshot with the following headings:
| Cust# | Last Trans. | Charge | Quantity |
Every month, I will receive a file from a third party with transactions that will add new cust# or change existing customer information. I am having problems when there are multiple updates to the same Cust# in one month.
For example:
processing the following transaction file:
should yield the following snapshot table:
It may not be the best method, but now I have 3 separate queries to handle NEW, CHANGE and CANCEL. There are no problems with NEW and CANCEL.
Here's how my CHANGE query is set up:
UPDATE snp
INNER JOIN tr
ON snp.[Cust#] = tr.[Cust#]
SET
snp.[Last Trans] = tr.Transaction,
snp.Charge = snp.Charge + tr.Charge,
snp.Quantity = tr.Quantity
WHERE tr.Trans='CHANGE'
Note that Charge is incremental and Quantity is not. Updating Charge is working as expected, but Quantity is not. I do not necessarily get the latest quantity.
How do I ensure that if there are any changes to one customer, that the last Quantity field taken is from the latest CHANGE row (ie. max ID of that cust#)?

SELECT * FROM snp
WHERE ID IN (SELECT MAX(ID)
FROM tr
GROUP BY CUST#)
The inner query would give you all customers' max ID. You can filter the cust# based on your change criteria. The outer query would give you all the details of that row. You can then use those values in your queries.

Related

Access Query Loop Update

I have a table with purchase orders, and all POs could have several entries with different items associated.
PO
PN
Status
1
A
Open
1
B
progress
1
C
Delivered
2
A
Open
3
A
Delivered
3
A
Delivered
From this master data Table, I would like to create a overview table, with just one entry per PO and only one Status information, according certain criteria.
Criteria example:
if one item is in PROGRESS or DELIVERED set PO status as PROGRESS
if one item is in OPEN (But don't exist PROGRESS) set PO Status as OPEN.
if all item is in PROGRESS or DELIVERED or OPEN set PO Status as PROGRESS or DELIVERED or OPEN accordingly.
OVERVIEW TABLE Example:
PO
Status
1
PROGRESS
2
OPEN
3
Delivered
I will offer one approach to consider. Assuming there are only 3 status categories:
Query1:
SELECT OrderDetails.PO,
Count(OrderDetails.PN) AS CntPN,
Sum(IIf([Status]="Progress",1,0)) AS CntP,
Sum(IIf([Status]="Open",1,0)) AS CntO,
Sum(IIf([Status]="Delivered",1,0)) AS CntD
FROM OrderDetails
GROUP BY OrderDetails.PO;
Query2:
SELECT Query1.PO, Switch([CntP]=[CntPN],"Progress", [CntO]=[CntPN],"Open", [CntD]=[CntPN],"Delivered", CntO>0 AND CntP=0,"Open", CntP>0 Or CntD>0,"Progress", True,Null) AS S
FROM Query1;
Query1 could be a CROSSTAB instead of using IIf() expressions to emulate. CROSSTAB will return Null instead of 0 so would have to deal with that. Then adjust Query2 structure for different field names.
Anything else will probably need a VBA custom function.

MS-Access 2021 Adding/Subtracting field entry from one table with the current value in another

I'm new to SQL and Access and am trying to take an entry from an InventoryTransactions.Quantity and summing it with another field from another table MasterInventory.QuantityOnHand. I know there is a way to do this with queries and forms but I'm kind of hitting a roadblock. Any help will be much appreciated!
Example
InventoryTransactions.Quantity (Table)
ID | TransactionItem | TransactionType | Quantity |
[ID] = Autonumber [TransactionItem] = Lookup referencing [.ID],[.ItemName], (Checking Y/N from [.Consumable]), all from [MasterInventory] [TransactionType] - Addition, Removal (Add, Subtract) from [TransactionTypeTable] Quantity - Number
MasterInventory
Here I want to add my record entry for Quantity in the above table and it to be added or subtracted (depending on the entry in the TransactionType field to .QuantityOnHand in this MasterInventory table
Say I've got 20 of something in [MasterInventory].[QuantityOnHand] and I enter 20 into the [ItemTransactions].[Quantity]
Saying that I selected "Addition" in [ItemTransactions].[TransactionType]
The new value in [MasterInventory].[QuantityOnHand] should now be updated to 40 for the corresponding [MasterInventory].[ID] field. (Updated to 0 if I selected "Remove" in [ItemTransactions].[TransactionType]
Let me know if you see this and need clarification please.

Multi-Row Per Record SQL Statement

I'm not sure this is possible but my manager wants me to do it...
Using the below picture as a reference, is it possible to retrieve a group of records, where each record has 2 rows of columns?
So columns: Number, Incident Number, Vendor Number, Customer Name, Customer Location, Status, Opened and Updated would be part of the first row and column: Work Notes would be a new row that spans the width of the report. Each record would have two rows. Is this possible with a GROUP BY statement?
Record 1
Row 1 = Number, Incident Number, Vendor Number, Customer Name, Customer Location, Status, Opened and Updated
Row 2 = Work Notes
Record 2
Row 1 = Number, Incident Number, Vendor Number, Customer Name, Customer Location, Status, Opened and Updated
Row 2 = Work Notes
Record n
...
I don't think that possible with the built in report engine. You'll need to export the data and format it using something else.
You could have something similar to what you want on short description (list report, group by short description), but you can't group by work notes so that's out.
One thing to note is that the work_notes field is not actually a field on the table, the work_notes field is of type journal_input, which means it's really just a gateway to the actual underlying data model. "Modifying" work_notes actually just inserts into sys_journal_field.
sys_journal_field is the table which stores the work notes you're looking for. Given a sys_id of an incident record, this URL will give you all journal field entries for that particular record:
/sys_journal_field_list.do?sysparm_query=name=task^element_id=<YOUR_SYS_ID>
You will notice this includes ALL journal fields (comments + work_notes + anything else), so if you just wanted work notes, you could simply add a query against element thusly:
/sys_journal_field_list.do?sysparm_query=name=task^element=work_notes^element_id=<YOUR_SYS_ID>
What this means for you!
While you can't separate a physical row into multiple logical rows in the UI, in the case of journal fields you can join your target table against the sys_journal_field table using a Database View. This deviates from your goal in that you wouldn't get a single row for all work notes, but rather an additional row for each matched work note.
Given an incident INC123 with 3 work notes, your report against the Database View would look kind of like this:
Row 1: INT123 | markmilly | This is a test incident |
Row 2: INT123 | | | Work note #1
Row 3: INT123 | | | Work note #2
Row 4: INT123 | | | Work note #3

SQL statement that retrieves formulas for two different dates in db

All,
I have three total tables. The first table 'rollup1' contains the number of views and number of clicks for a campaign, as well as a one-up number for the day field (largest number in column represents the current date) A second table 'rollup2' contains the earnings for the campaign. It also contains the same one-up number for the dayfield. The third table 'campaigns' contains the ID/names for the campaigns. campaigns.id = rollup1.id = rollup2.id and rollup1.day=rollup2.day
I want to generate an SQL query that lists the campaign id, name, specific calculated value from yesterday, and specific calculated value from today. The specific calculated value I'm looking for is (earnings/clicks)*1000.
The results will look like:
id | name | yesterday | today
a | Campaign1 | $0.05 | $0.010
I think I can use case statements, but I can't seem to get it correct. Here's what I have so far. It calculates the formula for yesterday, but not the one for today. I need these to be side by side.
select campaigns.id, campaigns.name, rollup1.views,rollup1.clicks,rollup2.costs,round((rollup2.costs/rollup1.views)*1000,2) as yesterday
from campaigns,rollup1,rollup2
where campaigns.id = rollup1.campaign_id and campaigns.id = rollup2.campaign_id
and rollup1.dayperiod = rollup2.dayperiod
and rollup1.dayperiod = (SELECT (max(rollup1.dayperiod) -1) FROM rollup1)
Thanks for any help you can provide.

Retrieving the latest transaction for an item

I have a table that lists lots of item transactions. I need to get the last record for each item (the one dated the latest).
For example my table looks like this:
Item Date TrxLocation
XXXXX 1/1/13 WAREHOUSE
XXXXX 1/2/13 WAREHOUSE
XXXXX 1/3/13 WAREHOUSE
aaaa 1/1/13 warehouse
aaaa 2/1/13 WAREHOUSE
I want the data to come back as follows:
XXXXX 1/3/13 WAREHOUSE
AAAA 2/1/13 WAREHOUSE
I tried doing something like this but it is bringing back the wrong date
select Distinct ITEMNMBR
TRXLOCTN,
DATERECD
from TEST
where DateRecd = (select max(DATERECD)
from TEST)
Any help is appreciated.
You're on the right track. You just need to change your subquery to a correlated subquery, which means that you give it some context to the outer query. If you just run your subquery (select max(DATERECD) from TEST) by itself, what do you get? You get a single date that is the latest date in the whole table, regardless of item. You need to tie the subquery to the outer query by linking on the ITEMNMBR column, like this:
SELECT ITEMNMBR, TRXLOCTN, DATERECD
FROM TEST t
WHERE DateRecd = (
SELECT MAX (DATERECD)
FROM TEST tMax
WHERE tMax.ITEMNMBR = t.ITEMNMBR)
No need for subquery. You are querying a single table and need to select MAX(date) and GROUP BY item and TrxLocation.
SELECT Item, max(DATERECD) AS max_dt_recd, TrxLocation
FROM test
GROUP BY Item, TrxLocation
/