MS Access error - Division by zero when executing query - ms-access-2013

I am using a Crosstab query to calculate the percentage from a pair of numbers and a Make query to put the result into a different table.
Source data is something like this:
ITEMS |PAIRS |VAL
Element1 |dividend |43
Element1 |divisor |33
Element2 |dividend |65
Element3 |dividend |73
Element4 |dividend |32
Element4 |divisor |23
Element3 |divisor |49
PLEASE NOTE: In a real situation, it is entirely possible that one of the two elements is missing (the divisor part of Element2, in this case).
Here is how I made the Crosstab query (named QCross) to overcome the 'Overflow' error.
TRANSFORM Sum(TRawData.Val) AS SumOfVAL
SELECT TRawData.ITEMS, IIf(IsError(Sum(IIf(TRawData.[PAIRS]='dividend', TRawData.[VAL],0))/Sum(IIf(TRawData.[PAIRS]='divisor',TRawData.[VAL],0))),0,Sum(IIf(TRawData.[PAIRS]='dividend',TRawData.[VAL],0))/Sum(IIf(TRawData.[PAIRS]='divisor',TRawData.[VAL],0))) AS MYRES
FROM TRawData
GROUP BY TRawData.ITEMS
PIVOT TRawData.PAIRS;
And this is the Make query
SELECT QCross.ITEMS, QCross.MYRES INTO TOutcome
FROM QCross;
The Crosstab query is working well, however I am dealing with a 'division by zero' error when the Make query is executed (!Run).
Can anyone help me to understand where the error is?

You code is not fast to comprehend, but a generic method is to check if the divisor is zero and, if so, replace with, say, 0 and 1 for dividend and divisor respectively to obtain a valid division and a result of 0:
result = IIf(divisor = 0, 0, dividend) / IIf(divisor = 0, 1, divisor)

Related

Business Objects 4.x: need to combine two queries similar to a UNION

I can't seem to figure out how to combine the result of 2 Business Objects queries.
Both queries return a set of codes and a number of hours. Query 1 can have codes that do not appear in Query 2, and Query 2 can have codes that do not appear in Query 1.
The resulting report should contain all codes from both Query 1 and Query2, a column with the sum of hours from Q1 for that code, and a column with the sum of hours from Query 2 for that code. If one of the queries doesn't have a code in it, it would return a blank or 0 total.
Example:
Q1 results:
|Code|Value|
|:---|:----|
|A|15|
|A|17|
|B|12|
|D|22|
|D|35|
|E|16|
|E|9|
|E|11|
Q2 results:
|Code|Value|
|:---|:----|
|A|5|
|A|19|
|B|33|
|C|17|
|C|24|
|E|78|
|E|12|
Report:
|Code|Value1|Value2|
|----|------|------|
|A|32|24|
|B|12|33|
|C| |41|
|D|57| |
|E|36|90|
|Total|137|188|
When I create the Business Object report table as normal, only the values of Query 1 are used, and I miss the row for value C. If I flip the queries around, I miss the row for value D.
How do I set up my report to show all the code values?
Edit: Sorry for the formatting of the tables, in the preview it looks perfect. :(

Max Val function not working as I expected it to work

I write this query I dont know why its not working for me can anyone suggest for me which is right
SELECT MAX(NVL(CPV.SR_NO,0)+1) INTO :CPV.SR_NO FROM CPV
WHERE VOUCHER_ID=4;
I have to bring MAX value I put 0 but it never bring 1 for first record after one record it worked properly mean if table is empty then first entry not give 1 after one record saved than its showed 1 even nvl is shown to null to 0 then + 1 please correct me
thanks
If there are no rows with VOUCHER_ID = 4, then you are taking MAX over zero rows, and that is always NULL - it doesn't matter what expression you are taking the MAX over. The NVL you used will only have effect if there are rows with VOUCHER_ID = 4, but in those rows you may have NULL in the SR_NO column. It won't help if there are no rows to begin with.
You could write the code like this **:
SELECT MAX(SR_NO) INTO :CPV.SR_NO FROM CPV WHERE VOUCHER_ID=4;
:CPV.SR_NO := NVL(:CPV.SR_NO, 0) + 1;
That is - apply the NVL (and also add 1) outside the SELECT statement.
With that said - what is the business problem you are trying to solve in this manner? It looks very much like an extremely bad approach, no matter what the problem you are trying to solve is.
** Note - I haven't seen qualified bind variable names before, like :CPV.SR_NO, but since the query works for you, I assume it's OK. EDIT - I just tried, and at least in Oracle 12.2 such names are invalid for bind variables; so I'm not sure how it was possible for your code to work as posted.
ANOTHER EDIT
The whole thing can be simplified further. We just need to pull the NVL out of MAX (and also the adding of 1):
SELECT NVL( MAX(SR_NO), 0) + 1 INTO :CPV.SR_NO FROM CPV WHERE VOUCHER_ID=4;

How to filter clickhouse table by array column contents?

I have a clickhouse table that has one Array(UInt16) column. I want to be able to filter results from this table to only get rows where the values in the array column are above a threshold value. I've been trying to achieve this using some of the array functions (arrayFilter and arrayExists) but I'm not familiar enough with the SQL/Clickhouse query syntax to get this working.
I've created the table using:
CREATE TABLE IF NOT EXISTS ArrayTest (
date Date,
sessionSecond UInt16,
distance Array(UInt16)
) Engine = MergeTree(date, (date, sessionSecond), 8192);
Where the distance values will be distances from a certain point at a certain amount of seconds (sessionSecond) after the date. I've added some sample values so the table looks like the following:
Now I want to get all rows which contain distances greater than 7. I found the array operators documentation here and tried the arrayExists function but it's not working how I'd expect. From the documentation, it says that this function "Returns 1 if there is at least one element in 'arr' for which 'func' returns something other than 0. Otherwise, it returns 0". But when I run the query below I get three zeros returned where I should get a 0 and two ones:
SELECT arrayExists(
val -> val > 7,
arrayEnumerate(distance))
FROM ArrayTest;
Eventually I want to perform this select and then join it with the table contents to only return rows that have an exists = 1 but I need this first step to work before that. Am I using the arrayExists wrong? What I found more confusing is that when I change the comparison value to 2 I get all 1s back. Can this kind of filtering be achieved using the array functions?
Thanks
You can use arrayExists in the WHERE clause.
SELECT *
FROM ArrayTest
WHERE arrayExists(x -> x > 7, distance) = 1;
Another way is to use ARRAY JOIN, if you need to know which values is greater than 7:
SELECT d, distance, sessionSecond
FROM ArrayTest
ARRAY JOIN distance as d
WHERE d > 7
I think the reason why you get 3 zeros is that arrayEnumerate enumerates over the array indexes not array values, and since none of your rows have more than 7 elements arrayEnumerates results in 0 for all the rows.
To make this work,
SELECT arrayExists(
val -> distance[val] > 7,
arrayEnumerate(distance))
FROM ArrayTest;

Division by zero error when executing query

I am using a Crosstab query to calculate the percentage from a pair of numbers and a Make query to put the result into a different table.
Source data is something like this:
ITEMS |PAIRS |VAL
Element1 |dividend |43
Element1 |divisor |33
Element2 |dividend |65
Element3 |dividend |73
Element4 |dividend |32
Element4 |divisor |23
Element3 |divisor |49
PLEASE NOTE: In a real situation, it is entirely possible that one of the two elements is missing (the divisor part of Element2, in this case).
Here is how I made the Crosstab query (named QCross) to overcome the 'Overflow' error.
TRANSFORM Sum(TRawData.Val) AS SumOfVAL
SELECT TRawData.ITEMS, IIf(IsError(Sum(IIf(TRawData.[PAIRS]='dividend', TRawData.[VAL],0))/Sum(IIf(TRawData.[PAIRS]='divisor',TRawData.[VAL],0))),0,Sum(IIf(TRawData.[PAIRS]='dividend',TRawData.[VAL],0))/Sum(IIf(TRawData.[PAIRS]='divisor',TRawData.[VAL],0))) AS MYRES
FROM TRawData
GROUP BY TRawData.ITEMS
PIVOT TRawData.PAIRS;
And this is the Make query
SELECT QCross.ITEMS, QCross.MYRES INTO TOutcome
FROM QCross;
The Crosstab query is working well, however I am facing with a 'division by zero' error when the Make query is executed (!Run); it worth to note the error doesn't comes up in 'View' mode.
Where am I doing wrong?
Crosstab query execution:
Make query (View mode):

Most efficient way to filter multiple dimensions

Trying to get the [Number] and [Sum of Time Spent] for all Changes that were open during period 201405.
The best definition of open I can think of is is:
- Changes that were logged before or during the [MonthPeriod], while closed during or after the [MonthPeriod]
SELECT
[Measures].[Sum of Time Spent] ON COLUMNS
,
[FactChange].[Number].[Number] ON ROWS
FROM
[Change Management]
WHERE
(FILTER(
[DimLoggedDate].[MonthPeriod].[MonthPeriod]
,[DimLoggedDate].[MonthPeriod].MEMBERVALUE <= 201405
)
,
FILTER(
[DimClosedDate].[MonthPeriod].[MonthPeriod]
,[DimClosedDate].[MonthPeriod].MEMBERVALUE >= 201405
))
The above query returns a list with all numbers, with a null value when the filters in the WHERE clause don't apply. I would like to remove the NULL items.
Because the query returns ALL Numbers, I wonder if this is the most efficient query to solve the issue. Applying NonEmpty() would remove the numbers, but since all changes are enumerated, isn't this putting more stress on the system than required?
You do it simply by adding "Non empty" in the on Rows clause:
...
non empty [FactChange].[Number].[Number] on Rows
...

Resources