MS Access Append Query - Field not working - sql

I have an append query which has an Excel Sheet as a datasource. Today the underlying data of one of the fields was changed from String to Long. In my query table I had this particular field calculated as:
MSCI: Left([bp_msci_ic_key];2)
in order to compensate for the change in underlying data format I changed it to...
MSCI: Left(*Str*([bp_msci_ic_key]);2)
Unfortunately, the query produces #ERROR with this... why does this approach not work?
Here the syntax of the entire SQL statement:
INSERT INTO tbl_Position(
MoPo_ID,
AssetClass_Sub_ID,
VALOR,
ISIN,
[Currency],
Position_Name,
Weight,
Rating,
Asset_Country,
Issuer_Country,
Position_Duration,
Position_YieldToMaturity,
MSCI_Code,
PosValue)
SELECT
qry_Position_Load_step1.MoPo_BM_ID,
qry_Position_Load_step1.AssetClass_Sub_ID,
qry_Position_Load_step1.VALOR,
qry_Position_Load_step1.ISIN,
IIf([qry_Position_load_step1]![ccy] Is Null And Left([qry_Position_load_step1]![classsub],2)="M_", Mid([qry_Position_load_step1]![classsub],3,Len([qry_Position_load_step1]![classsub])-1),[qry_Position_load_step1]![CCY]) AS CCY,
qry_Position_Load_step1.NAME_SHORT,
qry_Position_Load_step1.Val,
tbl_MopoRohdaten.rating_clir,
tbl_MopoRohdaten.ass_domi_country,
tbl_MopoRohdaten.iss_domi_country,
tbl_MopoRohdaten.pos_dur_mod,
tbl_MopoRohdaten.pos_ytm,
Left(Str([bp_msci_ic_key]),2) AS MSCI,
tbl_MopoRohdaten.pos_eop_value
FROM
qry_Position_Load_step1
LEFT JOIN tbl_MopoRohdaten ON
(qry_Position_Load_step1.MoPo_Name_Avaloq = tbl_MopoRohdaten.portf_name) AND
(qry_Position_Load_step1.ISIN = tbl_MopoRohdaten.asset_isin);
EDIT: A reduced Selection as per comments:
SELECT
tbl_MopoRohdaten.[bp_msci_ic_key] AS MSCI
FROM
qry_Position_Load_step1
LEFT JOIN tbl_MopoRohdaten ON
(qry_Position_Load_step1.MoPo_Name_Avaloq = tbl_MopoRohdaten.portf_name) AND
(qry_Position_Load_step1.ISIN = tbl_MopoRohdaten.asset_isin)
WHERE
(((tbl_MopoRohdaten.[bp_msci_ic_key]) Is Not Null));

The problem occurred because the underlying data had a broked/incomplete record source. For reasons I am not certain of yet, only a fraction of the underlying data in tbl_MopoRohdaten got loaded. Since the query used a double join in matching up the data, it kept on showing a number of records that matched one of the joins.
However, the results that were returned never contained any data for the MSCI field I was having problems with. So naturally, when I used CStr() it returned an error, because the field was Null.

Related

How to query only old and duplicate data from a database in SQL

I'm trying to query my database to pull only duplicate/old data to write to a scratch section in excel (Using a macro passing SQL to the DB).
For now, I'm currently testing in Access alone to only filter out the old data.
First, I'm trying to filter my database by a specifed WorkOrder, RunNumber, and Row.
The code below only filters by Work Order, RunNumber, and Row. ...but SQL doesn't like when I tack on a 2nd AND statement; so this currently isn't working.
SELECT *
FROM DataPoints
WHERE (((DataPoints.[WorkOrder])=[WO2]) AND ((DataPoints.[RunNumber])=6) AND ((DataPoints.[Row]=1)
Once I figure that portion out....
Then if there is only 1 entry with specified WorkOrder, RunNumber, and Row, then I want filter it out. (its not needed in the scratch section, because its data is already written to the main section of my report)
If there are 2 or more entries with said criteria(WO, RN, and Row), then I want to filter out the newest entry based on RunDate and RunTime, and only keep all older entries.
For instance, in the clip below. The only item remaining in my filtered query will be the top entry with the timestamp 11:47:00AM.
.
Are there any recommended commands to complete this problem? Any ideas are helpful. Thank you.
I would suggest something along the lines of the following:
select t.*
from datapoints t
where
t.workorder = [WO2] and
t.runnumber = 6 and
t.row = 1 and
exists
(
select 1
from datapoints u
where
u.workorder = t.workorder and
u.runnumber = t.runnumber and
u.row = t.row and
(u.rundate > t.rundate or (u.rundate = t.rundate and u.runtime > t.runtime))
)
Here, if the correlated subquery within the where clause finds a record with the same workorder, runnumber and row, but with either a later rundate or the same rundate and a later runtime, then the record is returned by the main query.
You need two more )'s at the end of your code snippet. Or you can delete the parentheses completely in this example, MS Access will ad them back in as it deems necessary.
M.S. Access SQL can be tricky as it is not standards compliant and either doesn't allow for super complex queries, or it needs an ugly work around, like having a parentheses nesting nightmare when trying to join more than two tables.
For these reasons, I suggest using multiple Access queries to produce your results.

How to resolve a Left Join sub-query error?

In MS-Access I'm trying to join three tables. The third table is created from a sub-query designed to aggregate dates because I don't want multiple records per day when aligned with the first table.
When I entered the left join sub-query, I got this error:
The field is too small to accept the amount of data you attempted to
add. Try inserting or pasting less data.
I've run the sub-query separately and it returns about 19,000 records. Which is quite smaller than the actual table. If I use the actual table, the query works just fine, but it includes the duplicate records when there is more than one entry per day on the third table.
SELECT
SUM([ACD Calls]),
(SUM([Avg ACD Time]*[ACD Calls])/SUM([ACD Calls]))/86400,
(SUM([Avg ACW Time]*[ACD Calls])/SUM([ACD Calls]))/86400,
((SUM([Hold Time])/SUM([ACD Calls])))/86400,
((SUM([Avg ACD Time]*[ACD Calls])
+ SUM([Avg ACW Time]*[ACD Calls]))/SUM([ACD Calls]))/86400,
SUM([Time Adhering])/SUM([Total Time Scheduled]),
SUM([SS])/SUM([SO])
FROM
(
(
[GroupSumDaily]
LEFT JOIN Adherence_WKLY ON (GroupSumDaily.[Day] = Adherence_WKLY.[Day])
AND (GroupSumDaily.Agent = Adherence_WKLY.Agent)
)
LEFT JOIN
(
SELECT Evaluation_List.[Agent],
Evaluation_List.Recording_Date,
SUM(Evaluation_List.[Score]) as SS,
SUM(Evaluation_List.[Out of]) as SO
From Evaluation_List
Group By Evaluation_List.[Recording_Date],
Evaluation_list.[Agent]
)
as Evals ON (GroupSumDaily.[Day] = Evals.[Recording_Date])
AND (GroupSumDaily.Agent = Evals.Agent)
)
WHERE
(
[GroupSumDaily].[Agent] = "LastName FirstName"
AND Month([GroupSumDaily].[Day]) =1
AND Year([GroupSumDaily].[Day]) =2018
AND [GroupSumDaily].[Day] > #2/23/2015#
)
It looks like you don't have a "main" table to query from.
I'd try removing the first two open brackets after the FROM statement (and their equivalent closing brackets.)
If that doesn't fix it, try moving the whole sub-query into a separate query and selecting from the results...
It turns out the subquery fields are automatically limited to 50 characters and this was the root of the problem. When I limited the return to LEFT([Agent], 50), the error disappeared. Is there a way to set character length is a subquery field?
The other odd things is, none of my fields were actually over 50 characters... when I ran Select [Agent] Where LEN([Agent]) >= 50, it returned only 1 records, and it was the "NEW" blank record from the bottom. I confirmed that it completely blank, with no spaces or tabs. Very confusing.

Query with Totals Query results as criteria returns the expected number of results squared

Background
I am building an Access 2010 database that has a table [ControllerAdjustments] that keeps track of all adjustments made to controllers with an [AdjustmentID] autonumber field, a [ControllerID] field, an [AdjustmentDate] field, [Setpoint] field, and a [Power] field. The [Power] field represents the power level when the adjustment was made. Ultimately I need two queries to return two sets of results, one query should return the current status of all controllers (basically the most recent adjustment made on each controller) and the other should return the most recent adjustment made on each controller where power level is 100%. I plan to use each of these queries to feed a report. Note: field names changed slightly for convenience when typing, full names given in the code blocks...
Method
I focused on the Current Query first, and figured I would just copy it and make necessary changes to create a 100% Query. I started with a totals query on the [ControllerAdjustments] table, that had [ControllerID] as a Group By field and [AdjustmentDate] as a field that returned the Max value. This query returns exactly the number of records I expected, and after reviewing the sample bogus data I put in the table to check it, it seems to return exactly the records I need. I then created a Select Query that returned all the fields I want in my Current Report, namely the [ControllerAdjustments] table and the related records in upstream related tables. I then set the criteria for the [ControllerID] field in my Select Query to equal [Total_CurrentContAdjs]![ControllerID] and the [AdjustmentDate] in the Select Query to [Total_CurrentContAdjs]![MaxOfAdjustmentDate]. Running this query returns exactly what I want. The SQL for this query is below:
SELECT List_Units.UnitID, List_EDTanks.TankNameShort, List_Controllers.ControllerType, ControllerAdjustments.AdjustmentDate, ControllerAdjustments.ControllerSetpoint, ControllerAdjustments.RxPower
FROM Total_ContAdjsCurrent, ((List_Units INNER JOIN List_EDTanks ON List_Units.UnitID = List_EDTanks.UnitID) INNER JOIN List_Controllers ON List_EDTanks.EDTankID = List_Controllers.EDTankID) INNER JOIN ControllerAdjustments ON List_Controllers.ControllerID = ControllerAdjustments.ControllerID
WHERE (((ControllerAdjustments.AdjustmentDate)=[Total_ContAdjsCurrent]![MaxOfAdjustmentDate]) AND ((ControllerAdjustments.ControllerID)=[Total_ContAdjsCurrent]![ControllerID]))
ORDER BY List_Units.Unit, List_EDTanks.TankSortOrder, List_Controllers.ControllerType DESC;
I then copied the Totals query and added a column for Power, selected Where, unchecked show, and put in 100 for criteria. This works as expected. I then copied my select query, and changed the criteria fields to direct to my new 100% Totals query. This is where my problems begin.
Problem
The second 100% Query does not seem to like the criteria, as it initially throws out the familiar parameter window. This is the SQL Statement for the second query, virtually the same except for referring to the 100% Totals query:
SELECT List_Units.UnitID, List_EDTanks.TankNameShort, List_Controllers.ControllerType, ControllerAdjustments.AdjustmentDate, ControllerAdjustments.ControllerSetpoint, ControllerAdjustments.RxPower
FROM Total_ContAdjsCurrent, Total_ContAdjsStdyState, ((List_Units INNER JOIN List_EDTanks ON List_Units.UnitID = List_EDTanks.UnitID) INNER JOIN List_Controllers ON List_EDTanks.EDTankID = List_Controllers.EDTankID) INNER JOIN ControllerAdjustments ON List_Controllers.ControllerID = ControllerAdjustments.ControllerID
WHERE (((ControllerAdjustments.AdjustmentDate)=[Total_ContAdjsStdyState]![MaxOfAdjustmentDate]) AND ((ControllerAdjustments.ControllerID)=[Total_ContAdjsStdyState]![ControllerID]))
ORDER BY List_Units.Unit, List_EDTanks.TankSortOrder, List_Controllers.ControllerType DESC;
Initially, Access did not add my Totals query into the show table box in design view, because its results were not directly used in the Select Query. So, I added the Totals query to the top, and that allowed my query to run without asking for parameters, but now it returns the number of results I was expecting squared. Basically if I am expecting 3 records: 1, 2, and 3, it is giving me: 1, 1, 1, 2, 2, 2, 3, 3, and 3. For the life of me I cannot figure out why it is doing this, especially because the exact same setup for my Current Query returns exactly what is expected... I thought maybe the where clause in my totals query had something to do with it, so I created a Select Query for the [ControllerAdjustments] table that returned all records with 100 for power. I then used this query for my totals query instead of the totals query itself, but this did not do anything different. I am at a loss, and not sure what else I can do to get the results I want. Any suggestions welcome, thank you!
I solved this by simply starting over from scratch and rebuilding my 100% query. Reviewing the SQL statements, they look identical, however for some reason my query now returns the right number of records. I have no idea why this worked, and am still curious what went wrong in the first place if anyone with time available cares to dig into it, but the original problem statement has been corrected--even if I have no idea how I did it haha...

SQL MIN() returns multiple values?

I am using SQL server 2005, querying with Web Developer 2010, and the min function appears to be returning more than one value (for each ID returned, see below). Ideally I would like it to just return the one for each ID.
SELECT Production.WorksOrderOperations.WorksOrderNumber,
MIN(Production.WorksOrderOperations.OperationNumber) AS Expr1,
Production.Resources.ResourceCode,
Production.Resources.ResourceDescription,
Production.WorksOrderExcel_ExcelExport_View.PartNumber,
Production.WorksOrderOperations.PlannedQuantity,
Production.WorksOrderOperations.PlannedSetTime,
Production.WorksOrderOperations.PlannedRunTime
FROM Production.WorksOrderOperations
INNER JOIN Production.Resources
ON Production.WorksOrderOperations.ResourceID = Production.Resources.ResourceID
INNER JOIN Production.WorksOrderExcel_ExcelExport_View
ON Production.WorksOrderOperations.WorksOrderNumber = Production.WorksOrderExcel_ExcelExport_View.WorksOrderNumber
WHERE Production.WorksOrderOperations.WorksOrderNumber IN
( SELECT WorksOrderNumber
FROM Production.WorksOrderExcel_ExcelExport_View AS WorksOrderExcel_ExcelExport_View_1
WHERE (WorksOrderSuffixStatus = 'Proposed'))
AND Production.Resources.ResourceCode IN ('1303', '1604')
GROUP BY Production.WorksOrderOperations.WorksOrderNumber,
Production.Resources.ResourceCode,
Production.Resources.ResourceDescription,
Production.WorksOrderExcel_ExcelExport_View.PartNumber,
Production.WorksOrderOperations.PlannedQuantity,
Production.WorksOrderOperations.PlannedSetTime,
Production.WorksOrderOperations.PlannedRunTime
If you can get your head around it, I am selecting certain columns from multiple tables where the WorksOrderNumber is also contained within a subquery, and numerous other conditions.
Result set looks a little like this, have blurred out irrelevant data.
http://i.stack.imgur.com/5UFIp.png (Wouldn't let me embed image).
The highlighted rows are NOT supposed to be there, I cannot explicitly filter them out, as this result set will be updated daily and it is likely to happen with a different record.
I have tried casting and converting the OperationNumber to numerous other data types, varchar type returns '100' instead of the '30'. Also tried searching search engines, no one seems to have the same problem.
I did not structure the tables (they're horribly normalised), and it is not possible to restructure them.
Any ideas appreciated, many thanks.
The MIN function returns the minimum within the group.
If you want the minimum for each ID you need to get group on just ID.
I assume that by "ID" you are referring to Production.WorksOrderOperations.WorksOrderNumber.
You can add this as a "table" in your SQL:
(SELECT Production.WorksOrderOperations.WorksOrderNumber,
MIN(Production.WorksOrderOperations.OperationNumber)
FROM Production.WorksOrderOperations
GROUP BY Production.WorksOrderOperations.WorksOrderNumber)

SQL - How to insert a subquery into a query in order to retrieve unique values

I am writing reports using Report Builder 3, and I need some help with an sql query to get unique values.
Using the following sample data:
I need to be able to get one single value for feeBudRec returned for each feeRef. The value of each feeBudRec is always the same for each individual feeRef (eg for every data row for feeRef LR01 will have a feeBudRec of 1177).
The reason why I need to get a single feeBudRec value for each feeRef is that I need to be able to total the feeBudRec value for each feeRef in a feePin (eg for feePin LEE, I need to total the feeBudRec values for LR01 and PS01, which should be 1177 + 1957 to get a total of 3134; but if I don't have unique values for feeBudRec, it will add the values for each row, which would bring back a total of 11756 for the 8 LEE rows).
My experience with writing SQL queries is very limited, but from searching the internet, it looks like I'll need to put in a subquery into my SQL query in order to get a single unique feeBudRec figure for each feeRef, and that a subquery that gets a minimum feeBudRec value for each feeRef should work for me.
Based on examples I've found, I think the following subquery should work:
SELECT a.feeRef, a.feeBudRec
FROM (
SELECT uvw_EarnerInfo.feeRef, Min(uvw_EarnerInfo.feeBudRec) as AvailableTime
FROM uvw_EarnerInfo
GROUP BY
uvw_EarnerInfo.feeRef
) as x INNER JOIN uvw_EarnerInfo as a ON a.feeRef = x.feeRef AND a.feeBudRec = x.AvailableTime;
The problem is that I have no idea how to insert that subquery into the query I'm using to produce the report (as follows):
SELECT
uvw_EarnerInfo.feeRef
,uvw_EarnerInfo.PersonName
,uvw_EarnerInfo.PersonSurname
,uvw_EarnerInfo.feePin
,uvw_RB_TimeLedger.TimeDate
,uvw_RB_TimeLedger.matRef
,uvw_RB_TimeLedger.TimeTypeCode
,uvw_RB_TimeLedger.TimeCharge
,uvw_RB_TimeLedger.TimeElapsed
,uvw_WoffTimeByTime.WoffMins
,uvw_WoffTimeByTime.WoffCharge
,uvw_EarnerInfo.feeBudRec
,uvw_EarnerInfo.personOccupation
FROM
uvw_RB_TimeLedger
LEFT OUTER JOIN uvw_WoffTimeByTime
ON uvw_RB_TimeLedger.TimeId = uvw_WoffTimeByTime.TimeId
RIGHT OUTER JOIN uvw_EarnerInfo
ON uvw_EarnerInfo.feeRef = uvw_RB_TimeLedger.feeRef
WHERE
uvw_RB_TimeLedger.TimeDate >= #TimeDate
AND uvw_RB_TimeLedger.TimeDate <= #TimeDate2
If that subquery will get the correct results, can anyone please help me with inserting it into my report query. Otherwise, can anyone let me know what I will need to do to get a unique feeBudRec value for each feeRef?
Depends on the exact schema, but assuming the uvw_EarnerInfo lists the Pin, Ref, and Rec without duplicates, try adding an extra column (after personOccupation) on the end of your query such as :
feeBudRecSum = (Select SUM(FeeBudRec) From uvw_EarnerInfo x
where x.feePin = uvw_EarnerInfo.feePin
Group By x.FeePin)
Note that you would not Sum these values in your report. This column should have the total you are looking for.
The key to Report Builder is to get your query correct from the offset and let the wizard then structure your report for you. It takes all the hard work out of structuring your report manually.
I haven't used Report Builder for a while now but in the query builder of the report displaying the graphical representation of your query you should be able to drag and drop columns in and out of the query set. Dragging a column upwards and out of the box (showing your columns) would have the effect of causing your report to break on this column.
If you restructure this way you will probably have to run the report generator again to regenerate the report and restructure it.
Once you are happy with the structure you can then begin to add the summary columns.