We want to build a report in Microsoft Dynamics AX 2009 to show all employees that worked on a production order.
Into the datasources for this report we drag-n-dropped the
ProdTable (pt) which is inner joined by ProdID and DataAreaID to the
ProdJournalRoute (pjr) which is inner joined by EmplID and DataAreaID to the
EmplTable (et) where we look up the employee's name via the name() method.
This report yields some funny output:
pjr.TransDate pjr.EmplID et.EmplID et.name()
2010-07-20 05820
2010-07-20 05820 05820 Doe, John
2010-07-20 05820 05820 Doe, John
2010-07-21 00341 05820 Doe, John
2010-07-21 00007 00341 Snow, Jon
... ... ... ...
(Columns and rows snipped)
See? Somewhere in the join between ProdJournalRoute and EmplTable the EmplID gains a one line offset.
Now I could of course simply copy the name() method from the EmplTable to the ProdJournalRoute table and drop the EmplTable join altogether, but I'm afraid this only postpones the problem: what can I do to get my join to work? Should I use a handcrafted query and use this as datasource for the report?
(PS: could perhaps somebody with the necessary user rights clean up all these
[[[microsoft] dynamics] AX] tags? Thank you!)
Check the relation between the tables ProdJournalRoute and EmplTable.
Set ProdJournalRoute.relations to Yes or add the relations manually.
Got it working.
I'm a little reluctant to admit that the solution was simple: when, out of clues, I rebuild the whole thing from scratch, I added all my ProdJournalRoute fields and EmplTable fields to the EmplTable_Body of the design instead of the ProdJournalRoute_Body like I did the first time around, and that made all the difference.
I still don't quite see how and where a report links the data it displays. I would think that the query should be executed as a whole, joining all the tables involved so that you simply can't get this kind of data discrepancy between tables, but there it is: a datasource <DS> is only refreshed in the <DS>_Body of the design. Using this datasource in the design body of a datasource that is joined further up the query gets weird results: either it is uninitialised, or it shows old data that it got from a join to a prior record.
Thank you again for your thoughts, Mr Kjeldsen.
It seems to me the tables aren't actually joined in the query, but the abstraction level creating the underlying queries are running first a single select on the outmost table, then running a query for the "joined" tables. That might explain why the first row has no data from the EmplTable. My guess is the query to the EmplTable didn't return the data quick enough for the framework. Take a look at the FirstFast property of the datasource and also what it does at MSDN: http://msdn.microsoft.com/en-us/library/aa842737(AX.10).aspx
I might be wrong, though. The only way to really know, is to try snitch the SQL run at the database.
Related
For background, I have 2 tables here. One is a JobTicket table with all of our required production info, and the other is a ScheduledItems table with all of our job ticket data, plus the dates we are supposed to run that Job. I am having no trouble getting all of the necessary data over there, my issue comes when I would like to do the opposite. I have created a Query to search for the Sales Order Number from both tables, and then set the criteria for Scheduled Items to null so it will only show the unscheduled Jobs. Query works great, shows me all of the jobs that have not been Scheduled yet, but for the life of me I cannot figure out the best way to go about filtering my Form JobTicket to show only those unscheduled Jobs. I don't want to just give my coworker those Query results and tell him to search Jobs one by one; some days we can get 25+ Jobs with 10+ Line Items, so the extreme end we would be looking at around 250 manual searches a day.
If anyone has dealt with this in the past and has any sort of jumping off point or recommendation for my methodology I would very sincerely appreciate it. Thanks all
the acess query
SELECT
Qry_JobTicket.Sales_Order_Number,
Qry_ScheduledItems.Sales_Order_Number
FROM Qry_JobTicket
LEFT JOIN Qry_ScheduledItems
ON Qry_JobTicket.Sales_Order_Number = Qry_ScheduledItems.Sales_Order_Number
WHERE (((Qry_ScheduledItems.Sales_Order_Number) Is Null));
Okay I have figured out how to go about it, all though I am sure it's not the best in the way of design principles. Here goes:
After creating the Query (SQL shown above, Qry_UnscheduledList) to find all of the Un-Scheduled Jobs, I created another query that brought in my Qry_JobTicket and my Qry_UnscheduledList. I inner joined on Sales Order Number, so we only see the Jobs yet to be scheduled, and brought in every field from Qry_JobTicket. Once that was done, I then created a button on my form and inserted the code below to change the Form's Record Source, similarly to as #HansUp suggested with the FormFilter property.
Private Sub Btn_ToBeScheduled_Click()
DoCmd.OpenForm "Frm_JobTicket"
With Forms("Frm_JobTicket")
If .RecordSource = "Qry_JobTicket" Then
.RecordSource = "Qry_ToBeScheduled"
ElseIf .RecordSource = "Qry_ToBeScheduled" Then
.RecordSource = "Qry_JobTicket"
End If
End With
End Sub
Now as I said earlier this may not be the best designing, but I was doing research for about an hour and couldn't find very many people who needed to filter their FormA records based off of corresponding records that don't exist in their FormB.
I have a bunch of data and I want the output to display an average of all the data points but also the individual data points in subsequent columns. Ideally it would look something like this:
Compound | Subject | Avg datapoint | Datapoint Experiment 1 | Datapoint Exp 2 | ...
..........XYZ......|.....ABC....|............40...............|...............20..............................|...............60...............|......
..........TUV......|.....ABC....|............30...............|...............20..............................|...............40...............|......
..........TUV......|.....DEF....|............20...............|...............10..............................|...............30...............|......
One problem I'm running in to is that I get repetitive lines of information. Another is that I have some rows pulling in info that doesn't apply, such that some of the individual datapoints in, say, row 2 would have info from subject DEF when I only want it to have info from subject ABC.
I hope this makes sense! I'm currently using inner join with a ton of where qualifiers. I'm close but not quite there. Any help is appreciate and let me know if I can provide additional info to help you help me.
The SQL language has a very strict rule requiring you to know the exact number of columns for your result set in advance, before looking at any data in your tables.
Therefore, if this average is based off a known fixed number of columns, or if the number of potential columns is reasonably small, where you can manually setup placeholders, then this will be possible. The key search terms to learn how to do this is "conditional aggregation", where you may also need to join the table to itself for each field.
Otherwise, you will need to pivot and aggregate your data in your client code or reporting tool.
I'm new to MS Access and am trying to speed up a data gathering process that is taking forever in Powershell. In Powershell I have 10 or so web API calls to get data and each comes back as an object with multiple properties (fields.) Each set of data has related fields to 1 or more of the other sets of data. Getting the data is very quick but piping an array of objects to where-object to select-object takes over an hour and there's really not that much data. Each object contains 500-1500 "records" and 5 to 10 "fields" so I thought why not export that data and use something that's intended to search through data to do the job? I exported each object as a separate .CSV file. So enter MS Access..
I imported each of the CSV's as a separate table (easy enough.) I'm going to simplify this down for this example to the following 3 tables:
[Tables]https://i.stack.imgur.com/UCH1F.jpg
Every table has fields that relate it over to other tables. Pretty much there's some sort of Id field in every table that is related to another Id field in a different table that I need to pull a field called "name" from. I'm trying to follow the bread crumbs from the Player name to it's Network name to it's Application name, to it's Layout name, etc... I want to build a query that I would eventually just be able to export as an Excel file. I also would prefer to just write out the SQL unless it's really easier to to understand the visual query builder. I'm looking to build a sheet with the following information:
Player's Name would include all names from the Players table and getting just that data makes sense to me. SELECT Name AS PlayerName FROM Players Everything else, not so much. I feel like this will end up being some mega query as I get deeper into related table after related table. In Excel, it would be straightforward using Vlookups across tabs but that doesn't seem to be the best approach. Given the info above, I'm trying to achieve the following output:
Result table
Any help with strategy and syntax greatly appreciated!
You're looking for the JOIN clause.
SELECT
Players.Name PlayerName, Networks.Name PlayerNetwork, Applications.Name ApplicationName
FROM
Players
LEFT OUTER JOIN
Networks
ON
Networks.ID = Players.NetworkId
LEFT OUTER JOIN
Applications
ON
Applications.Id = Players.ApplicationID
I have two tables
Email Contact History
Place of Service
that share a primarymembercustomerid. The Email Contact History has three fields:
Campaigncode
Primarymembercustomerid
maildate
and the Place of Service table has three fields
primarymembercustomerid
servicedate
serviceshortDesc
primarymembercustomerids are selected for E-mail campaigns, then if they walk into one of our branch offices and receive services, they show up in the Place of Service table. I want to count the number of primarymembercustomer ids that are mailed, and right next to it I want to have a count of primarymembercustomerids that showed up to a branch office.
What I have so far:
select
ch.campaigncode,
pos.serviceshortdesc,
count(ch.primarymembercustomerid),
count(pos.primarymembercustomerid)
from mktprodvm.cdmv_prmmbr_contacthist_email ch
right outer join mktprodvm.cdmv_pos pos on ch.primarymembercustomerid = pos.primarymembercustomerid
where ch.campaigncode = 'EDT_ALLACMO'
and pos.servicedate between '2017-02-01' and '2017-02-28'
group by 1,2
What I'm ending up with is a count of primarymembercustomerids that walk into a branch for that time period, but I'm not getting the total count of primarymembercustomerids that were E-mailed. I thought that by doing a right outer join I would get the total number of primarymembercustomerids that were mailed, but it's not working for me. I feel like I need to do some kind of subquery or correlated subquery, but I've ready about how to use them and I don't think that's right. I've never used them before and to be quite honest I'm not that great of a SQL coder either. Thanks for any help!
Because my low reputation on this site I can't comment, so I'm writing this as an answer.
I think that you are using the wrong type of join (or writing the tables in the wrong order). If you don't want to lose rows of your main table, the Email Contact History, you have to do a LEFT JOIN not a RIGHT JOIN.
Also, I don't know if it's possible, but I'm guessing that a primarymembercustomerid can have more than one service and since you are selecting the serviceshortdesc, a single Email might count in different rows of your anwerset and the total won't be accurate. According to what you said you want, I don't see a reason for including the service description in the SELECT.
I am writing a program that performs operations on a database of Football matches and data. One of the issues that I have is that my source data does not have consistent naming of each Team. So Leyton Orient could appear as L Orient. Most of the time this team is listed as L Orient. So I need to find the closest match to a team name when it does not appear in the database team name list exactly as it appears in the data that I am importing. Currently in my database I have a table 'Team' with a data sample as follows:
TeamID TeamName TeamLocation
1 Arsenal England
2 Aston Villa England
3 L Orient England
If the name 'Leyton Orient' appears in the data being imported I need to match this to L Orient and get the TeamID 3. My question is, can I use the LIKE function to achieve this in a case where the team name is longer than the name in the database?
I have figured out that if I had 'Leyton Orient' in the table and was importing 'L Orient' I could locate the correct entry with:
SELECT TeamName FROM Team WHERE TeamName LIKE '%l%orient%';
But can I do it the other way around? Also, I could have an example like Manchester United and I want to import Man Utd. I could find this by putting a % sign between every character like this:
SELECT TeamName FROM Team WHERE TeamName LIKE '%M%a%n%U%t%d%';
But is there a better way?
Finally, and this might be better put in another question, I would like not to have to search for the correct team when the way a team is named is repeated, i.e. I would like to store alternative spellings/aliases for teams in order to find the correct team entry quickly. Can anybody advise on how I might approach this? Thanks
The solution you are looking for is the FULL TEXT SEARCH, it'll require your DBA to create a full text index, however, once there you can perform much more powerful searches than just character pattern matching.
As the others have suggested, you could also just have an Alias table, which contains all possible forms of a team name and reference that. depending on how your search is working, that may well be the path of least resistance.
Finally, and this might be better put in another question, I would like not to have to search for the correct team when the way a team is named is repeated, i.e. I would like to store alternative spellings/aliases for teams in order to find the correct team entry quickly. Can anybody advise on how I might approach this? Thank
I would personally have a team table and a teamalias table. Use relationships to marry them up.
I believe the best way to prevent this, is to have a list of teams names displayed in a dropdown list. This will also let you drop validation for the team name. The users can now only choose one set team name and will also make it much easier for you working in your database. then you can look for the exact team name as it appears in your database. i.e.:
SELECT TeamName FROM Team WHERE TeamName = [dropdownlist_name];