Microsoft Access Query is too complex to run - IF formula - ms-access

I have a query in Access Database and when I try to run it, I get an error message "query is too complex to run." Runtime error 3360." The problem is with one formula / programming logic, see below:
Previously the formula was the below - and it worked.
IIf([BegTaxBasis]=0 And [Contribution]+[Distribution]=0,
0,
IIf([BegTaxBasis]=0 And [TaxIncSubTotal]=0,
-[Distribution],
IIf([Distribution]=0,
0,
IIf([TBBLL]+[Recourse]+[QualifiedNonrecourse]+[NonRecourse]<[Distribution],
-[Distribution],
0))))
Then I updated it to, see below:
IIf([BegTaxBasis]=0 And [Contribution]+[Distribution]=0,
0,
IIf([BegTaxBasis]=0 And [TaxIncSubTotal]=0,
-[Distribution],
IIf([Distribution]=0,
0,
IIf([TBBLL]>0,
0,
IIf([TBBLL]+[Recourse]+[QualifiedNonrecourse]+[NonRecourse]<[Distribution],
-[Distribution],
IIf([TBBLL]+[Recourse]+[QualifiedNonrecourse]+[NonRecourse]>[Distribution] And [TBBLL]+[Recourse]+[QualifiedNonrecourse]+[NonRecourse]<0 And [TaxIncSubTotal]<0,
[TBBLL]+[Recourse]+[QualifiedNonrecourse]+[NonRecourse]-[TaxIncSubTotal],
[TBBLL]+[Recourse]+[QualifiedNonrecourse]+[NonRecourse])))))
And now the query wont run, any help is much appreciated, thanks!

You could try assigning intermediate values to a separate field or fields, then reference such fields in the final expression. This will only work for certain queries and SQL clauses, but you didn't give a context for your formula so I can't comment more on your particular code. These type of intermediate field values cannot be referenced in JOIN, ORDER BY or WHERE clauses--only in other SELECT fields. The order of the fields is important... the field must be defined before referencing it later in the SQL statement.
This facilitates re-use of duplicate expression, e.g. [TBBLL]+[Recourse]+[QualifiedNonrecourse]+[NonRecourse], so it can shorten the overall query.
For example:
SELECT ([TBBLL]+[Recourse]+[QualifiedNonrecourse]+[NonRecourse]>[Distribution]
And [TBBLL]+[Recourse]+[QualifiedNonrecourse]+[NonRecourse]<0
And [TaxIncSubTotal]<0) As Condition1,
([TBBLL]+[Recourse]+[QualifiedNonrecourse]+[NonRecourse]-[TaxIncSubTotal]) As TrueValue1,
([TBBLL]+[Recourse]+[QualifiedNonrecourse]+[NonRecourse]) As FalseValue1,
Iif([Condition1],[TrueValue1],[FalseValue1]) As FalseValue2,
...
[Some final calculation using previous fields] As FinalValue
A similar technique is to calculate some values in another saved or embedded query then join to that query and reference the partial calculations for the final expression. This technique can overcome the limitations of defining fields in the same select query. For instance, this would allow using intermediate calculated values in a join expression, whereas the first technique would not allow that. Using a series of saved, joined queries would circumvent single-query length limitations as mentioned by June7.

Related

SSRS 2008 :Is it possible to specify an entire where clause within parameter?

I have a table that I am building a report for. There are about 10 fields, but 4 of those fields may contain value(s) that users would want to filter the report by.
I was thinking I could create a parameter with a list of label/value pairs and the value portion of the parameter item would be an actual where clause for the underlying dataset like:
#filter
label/value
exceptions/where error_field like '%exception%'
counts/where count_field > 100
2016/where year_field = 2016
I tried dataset:
select error_field, count_field, year_field from mytable
#filter
I also tried(leaving where out of parameter value):
select error_field, count_field, year_field from mytable
where #filter
Both dataset queries failed to save. I am thinking I could include all the varying where clauses inside the dataset query statement, but it may require different parameters but how can they be empty unless I used 1=1 as default value. I only wanted to use a single parameter tho.
Any other ideas?
Thank you.
Your dataset query needs to be valid SQL. You can use an expression for the dataset, and work with the SSRS expression language to generate the SQL you need.
Something like:
="SELECT * FROM TABLE " + IIF(Value = True," WHERE 'A' = 'B'","")
However, I think they are a pain to work with. They are harder to understand, and take longer to maintain, and much easier to contain a mistake.
I find it easer and safer just to pass the parameters to a SQL Stored Procedure on the server, especially if you are using a TEXT BOX entry field.

Filter Multivalue Parameter on Dataset

So I have a multiple value parameter than contains 3 options. >250K, <250K, >2M.
I also have a table that consists of multiple columns.
. Because the parameter is a multivalue, i am having difficulties filtering the dataset.
I need to filter the dataset by checking, (if > 250K is selected, filter the dataset accordingly), (if < 250K is selected, filter the dataset accordingly) and (if > 2M is selected, filter the dataset accordingly).
I was told to use a join and split on the parameter within the (>250K condition, then do a contains to see if it contains any of the parameter values) but I am not as advanced in my knowledge of coding to be able to do that.
Any Suggestion? Thanks in Advance
I previously tried the method below but then i came to realise that it wont work because the parameter is a multi value.
I know its been a while since you raised this, you were on the right track but all you should need to do is add a filter to the Tablix on the field you will be filtering, use the 'in' operator and in the Value type [#Yourparametername] the square brackets and case sensitivity are important. Also ensure the expression type is correct, in your case it looks like you are using Integer. The image should help.
If you want to use multi-parameters, In the dataset, you can read parameter value using JOIN.
Example:
If you want to read multiple values for #MyParamter in a dataset given in the following example:
Dataset Parameters
you need to use =JOIN(Parameters!myMultiParamter.Value,",") as an expression to read all selected values in CSV form.
Expression
Now the #ParameterValues param has all selected values as comma separated values and you can use them in your dataset code as per design requirements.
Note: It's not necessary to use a comma but u can use anything you want to separate values.
Your sql query where should look like
Where
(
(0 IN (#Parameter) AND ValueColumn<250000)
OR
(1 IN (#Parameter) AND ValueColumn>=250000)
OR
(2 IN (#Parameter) AND ValueColumn>=2000000)
)
One parameter
Two parameters
All parameters
Once you return the value you can also use charindex or patindex* and look for where the value in your where clause is a pattern where the index number is > 0 . For instance if the returned string from SSRS is '01,02,03' and then your where clause has something like this right(field, 2) which would result in value '03'. you change your where clause to be where patindex('%' + right(field, 2) + '%', #returnedstring) > 0 which will give you results. The keeps you from having to parse apart the #returnedstring parameter in your sql code.

SSRS <<expr>> error with sum

I have two equations on the same dataset. One returns an error, the other does not. The equations are as follows:
1) =Sum(IIF(Fields!Service.Value="Dispatch Only", 0, Fields!Charge.Value))
2) =Sum(IIF(Fields!Service.Value="DispatchOnly", 0, Fields!Charge.Value))
Note that the only difference between the two is the fact that I took a space out of the field I'm looking for.
I want a total sum of the entire data set. But then I also need to know what that same sum is, without the "Dispatch Only" values. Obviously, equation #2 doesn't produce any useful information (it's just the sum again), but I added it just to prove I wasn't insane with some very basic typo, like a comma out of place.
What am I doing wrong with equation #1??
This commonly occurs when applying an aggregate on differing data types, which you're unlikely to get unless you have an IIf statement, like in your example.
You're probably getting a mismatch between Charge and 0 (i.e. between the underlying data type of Charge and the integer 0).
To get around this, make sure that 0 is the same data type as Charge, i.e. use something like CDec(0) or CDbl(0) as required.
One other option to consider is to use Nothing in place of 0 - by using the SSRS null value you avoid any data type clashes, but it does have the disadvantage of returning Nothing if there are no matching Dispatch Only rows.

MS Access Query using IFF to compare values

I am trying to build a query which will look at the data in two fields in two different tables and check to see if the data is the same, if it is I want it to return the number of times it is matched, if it isn't I simply want it to return the text saying "No viewings".
I have constructed this query in my access database which has the field from the first table "Property" and the second field I want it to compare the data with, "Viewings". I have build the following expression using the build tool, however I am stuck to make it work since every time I get this error message when trying to run the query: "Your query does not include the specified expression 'Property Viewed' as part of an aggregate function."
totalViewings: IIf([Viewings]![Property Viewed]=[Property]![ID],Count([Viewings]![Property Viewed]=[Property]![ID]),"No Viewings")
Any help how to overcome this error would be very appreciated.
Thanks
I would suggest doing something like this:
1) Assuming this is something you are developing yourself, make sure your data structure is all in order first. Since I dislike relatively code-hostile identifiers, I'd have the tables as so -
Properties - PropertyID (AutoNumber, primary key), HouseNumberOrName, Street, etc.
Viewings - ViewingID (AutoNumber, primary key), PropertyID (Number/Long Integer), ViewingDate, etc.
In the Relationships view, Properties.PropertyID would then be set up to point to Viewings.PropertyID in a one-to-many relation.
2) Your actual query I would then break into two, the first to compile the data and the second to format it for display. The first would go like this, saved as ViewingCounts...
SELECT Properties.PropertyID, Count(Viewings.PropertyID) As ViewingCount
FROM Properties LEFT JOIN Viewings ON Properties.PropertyID = Viewings.PropertyID
GROUP BY Properties.PropertyID;
... and the second like this, saved as ViewingCountsForDisplay:
SELECT Properties.*, IIf(ViewingCount = 0, 'No viewings', ViewingCount) AS Viewings
FROM Properties INNER JOIN ViewingCounts ON Properties.PropertyID = ViewingCounts.PropertyID
ORDER BY Properties.PropertyID;

Paging Results: Handling invalid passed data

Have a simple page that pulls results from MySQL and displays them in a table. I have enabled paging on the results, and allowed the user to set the number of results being displayed per page. I am passing two querystring values to handle this: 'page' and 'count'.
I am then taking these values to calculate the LIMIT's of my MySQL query, using the SQL_CALC_FOUND_ROWS directive and following that with a call to SELECT FOUND_ROWS(); to get the total number of results. This all works nicely.
Now, I want to validate the querystring values. As I am storing the possible "correct" values for the results/page value of 'count' in an array, I simply check that the passed 'count' value is in that array, and if not set it to the default value. For the 'page' value, I am having a bit of a mental block... in order to determine if there are any results for the passed 'page', meaning it is "correct", I need to go to the database and find the result count first, but since I only want to go to the db once, I need to include the LIMIT's, which are based on the passed 'page' value... chicken and egg. I have a couple thoughts on how to solve this:
Run the query as coded above, and if the (('page' - 1) * 'count') result is greater than the value returned from SELECT FOUND_ROWS();, re-run the query with new LIMIT's set to 0, count.
Get the full result set, verify that the passed page is correct, then do another pull from the database with the LIMIT values.
I'd rather not go back to the database at all, but as I mentioned, having a mental block on this rather common issue.
Thanks,
Paul
I ended up using the first solution above -
Run the query as coded above, and if the (('page' - 1) * 'count') result is greater than the value returned from SELECT FOUND_ROWS();, re-run the query with new LIMIT's set to 0, count.
It's not perfect in that a second database pull is required for cases where the passed page value is bad, but given that is an unexpected case only triggered by the intentional passage of bad data on the part of the user, it's acceptable. If anyone else has a better solution, I'd be happy to re-open the question.