I am currently using Access 2016 and am trying to create a query that is pulling in a different query and a table as its 2 source elements. Below is an example of the structure
table:
entity code
legal AP01
admin AP02
acct AP03
query1:
date total billing
1/1/2019 $10 000000-AP01-abcxyz
1/5/2019 $12 000000-AP01-abcxyz
1/12/2019 $15 000000-AP02-abcxyz
I've tried thinking about how to do a join, but since the billing field is a long text due to the fact that some strings are much larger than 255 characters, that is out of the question. So maybe using IN somehow, and the query would look for the code field value in table within the billing field value in query1, and display the following output
query2:
date total billing entity
1/1/2019 $10 000000-AP01-abcxyz legal
1/5/2019 $12 000000-AP01-abcxyz legal
1/12/2019 $15 000000-AP02-abcxyz admin
Using that output I could group by entity and sum total to show total spend within a department. I dont want to have to extract down to excel, run vlookup and find, then re-import it back in to access. There would be no point if I wanted to just do it all in excel. Can this be done within an access query?
You can use instr():
select q1.*, t1.entity
from q1 join
t1
on instr(q1.billing, t1.code) > 0
You can use like:
select
q.*, t.entity
from query1 as q inner join tablename as t
on q.billing like '*-' & t.code & '-*'
From your expected results I assume that code will always be inside billing in the form: ...-AAAA-....
If this is not the case, remove the dashes and use it like this:
on q.billing like '*' & t.code & '*'
I have a txt file I'm reading that looks something like this...
Acct |Name |Date |Country
11111,FirstLast,01/01/2015,United States
11111,FirstLast,,
11111,,01/01/2015,
22222,FirstLast,02/02/2015,Kuwait
22222,FirstLast,,
22222,,02/02/2015,
33333,FirstLast,02/02/2015,France
33333,FirstLast,,
33333,,02/02/2015,
I'm creating a dataTable to fill with this data, and am adding a column called "LINE" to keep track of how many lines of data each account has. I then do a dataView sorting to sort like this:
dataView.Sort = "Acct ASC, Line ASC, Country ASC"
My output sorts by the acct and line#, but not by the country. So I'm getting this back...
Acct |Name |Date |Country |Line
11111,FirstLast,01/01/2015,United States,1
11111,FirstLast,,,2
11111,,01/01/2015,,3
22222,FirstLast,02/02/2015,Kuwait,1
22222,FirstLast,,,2
22222,,02/02/2015,,3
33333,FirstLast,02/02/2015,France,1
33333,FirstLast,,,2
33333,,02/02/2015,,3
What I want to get back is this because the main thing is to keep the same acct# records together, while sorting by country ascending...
Acct |Name |Date |Country |Line
33333,FirstLast,02/02/2015,France,1
33333,FirstLast,,,2
33333,,02/02/2015,,3
22222,FirstLast,02/02/2015,Kuwait,1
22222,FirstLast,,,2
22222,,02/02/2015,,3
11111,FirstLast,01/01/2015,United States,1
11111,FirstLast,,,2
11111,,01/01/2015,,3
I then realized that obviously this isn't working because the account number takes precedence in the sortation.
The big issue is that I have to use .NET 2.0, is there some way I can group these and sort by the country field?
Ideally this type of sorting can be implemented in the display such as GridView/DataGridView by Grouping the fields by Acct and then sorting within the groups as Country Desc, Line Asc.
If you want it to be sorted within the DataTable then you can accomplish by adding another dummy column to the DataTable.
Add another column to the DataTable e.g. Grp1
Sort DataTable by Acct Asc and Country Desc (so that country name always comes first and blanks later)
Iterate DataTable in a for loop (NOT For Each)
3.1. If Country is empty then set country = country in previous row (skip row 0, assuming country in row 0 always has a value)
3.2. Within same loop (outside and after if block) set the value of Grp1 column to Country - Acct
Now sort your DataTable again by Grp1 and Line
Putting it all together:
dt1.Columns.Add("Grp1")
dt1.DefaultView.Sort = "Acct Asc, Country Desc"
For i = 0 to dt1.Rows - 1
If i > 0 AndAlso dt1.Rows(i).Item("Country").ToString.Length = 0 Then
dt1.Rows(i).Item("Country") = dt1.Rows(i - 1).Item("Country").ToString
End If
dt1.Rows(i).Item("Grp1") = dt1.Rows(i).Item("Country").ToString & " - " & dt1.Rows(i).Item("Acct").ToString
Next
dt1.DefaultView.Sort = "Grp1 Asc, Line Asc"
I have this working in Excel however it really needs moved into Access as that's where the rest of the database resides.
Its simply one table that contains Unique_ID, Seller and Fruit...
1 Chris Orange
2 Chris Apple
3 Chris Apple
4 Sarah Kiwi
5 Chris Pear
6 Sarah Orange
The end results should be displayed by Seller and then a list of each fruit sold (in the following example Robert has not sold any fruit, I do have a list of all sellers name however this could be ignored in this example as that I believe that will be easy to integrate.) They will only sell a maximum of 20 fruit.
Seller 1st 2nd 3rd 4th
Chris Orange Apple Apple Pear
Sarah Kiwi Orange
Robert
At the moment Excel uses Index, Match and Small to return results. Small is simply used on the Unique_ID to find the 1st, 2nd, 3rd, ect...smallest entries and is matched to each sellers name to build the above results.
As Access doesn't have a Small function I am at a loss! In reality there are over 100,000 records (minimum) with over 4000 sellers....they are also not fruit :)
TRANSFORM First(Sales.Fruit) AS FirstOfFruit
SELECT Sales.Seller
FROM Sales
GROUP BY Sales.Seller
PIVOT DCount([id],"sales","seller='" & [seller] & "' and id<=" & [id]);
Where the table name is "Sales" and the columns are "ID", "Seller" and "Fruit"
To understand DCount better, use it is a SELECT query instead of a crosstab:
SELECT Sales.ID, Sales.Seller, Sales.Fruit, DCount([id],"sales","seller='" & [seller] & "' and id<=" & [id]) AS N
FROM Sales;
On each row, the last column is the DCount result. The syntax is DCount (field, source, expression) so what it does is count the IDs (field) in the Sales table (source) that match the expression - in other words, has the same seller as that row's record and an ID <= the current row's ID. So for Chris's sales, it numbers them 1 through 4, even though Sarah had a sale in the middle.
From this result, it's easy to take a Crosstab query that makes a table with seller in the row and N in the column - putting the sales in order for each seller the way you wanted to see them. The "First" function finds the first fruit for the combination of seller and N for each row and column of the result. You could just as easily use "Max" or "Min" here - any text function. Of course, there is only one record matching the seller row and the N column, but Crosstab queries require a function to evaluate and cannot use "Group by" for the field selected as a Value.
My 1st answer combines these steps - the select and the crosstab queries - in one query.
Hope this helps.
So each day I'm given an Excel worksheet with orders, they look something like this:
Date Vendor OrderID/Quantity Total
12/28/2013 Nike 1111111-8;2222222-12 20
12/29/2013 Adidas 3333333-5;4444444-10 15
12/30/2013 Wrangler 5555555-3 3
It's usable to most people I work with but not to me, as I want to identify each OrderID separate from the quantity. The "-" between the 7 digit number is to separate the ID from how many units are associated to it. But essentially when I import this table into access I want to create another table that splits these values.
Date Vendor OrderID Quantity
12/28/2013 Nike 1111111 8
12/28/2013 Nike 2222222 12
12/29/2013 Adidas 3333333 5
12/29/2013 Adidas 4444444 10
12/30/2013 Wrangler 5555555 3
This is much more useful to me but has been a daunting task to produce with two delimiters("-" and ";"). I am ok with VBA but I am struggling to find a solution to my conflict. So how would I go about doing this?
The most straightforward way I can think of is the VBA Split function. Please note that I set up the tblStaging staging table with all the fields as Text type for the import from Excel, but I set the tblOrders table up with (what I assume are) the correct types: Date as Date, Vendor as Text, OrderID as Number and Quantity as Number. See the comments in the code for details.
Public Sub SplitOrders()
Dim rsStaging As Recordset
Dim rsOrder As Recordset
Dim arrOrders() As String
Dim arrOrderDetails() As String
'Rename these for whatever your tables are called'
Set rsStaging = CurrentDb.OpenRecordset("tblStaging")
Set rsOrder = CurrentDb.OpenRecordset("tblOrders")
rsStaging.MoveFirst
While Not rsStaging.EOF
'Split into an array of Orders'
arrOrders = Split(rsStaging.Fields("OrderID/Quantity"), ";")
For i = 0 To UBound(arrOrders)
'Split the OrderID and Quantity for each Order'
arrOrderDetails = Split(arrOrders(i), "-")
'Create the new record in tblOrders'
With rsOrder
.AddNew
!Date = CDate(rsStaging!Date)
!Vendor = rsStaging!Vendor
!OrderID = CLng(arrOrderDetails(0)) 'If the OrderID can contain letters, symbols or leading zeros, omit the CLng( ... ) call'
!Quantity = CLng(arrOrderDetails(1))
.Update
End With
Next
rsStaging.MoveNext
Wend
End Sub
I'd look to break this down into different pieces rather than trying to parse the data all at once. For example, step 1 might be to import the file to a staging table (that looks like the first data example from your question). Step 2 would be to query the table to detect any rows that contain ';' (perhaps using the InStr function or a wildcard search like '*;*'. Take these records and parse them into two or more records. Third, identify any records that do not contain ';' and parse those into single records. All of the resulting (clean) records can go into your destination table for further analysis.
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.