When have a issue at work where the value returned by the SUM() function isn't treated like a "normal" number when using the value returned together with the Round() function.
Try this MDX for example
WITH
MEMBER SomeNumber AS 0.595
SET SomeNumberSet AS
{[SomeNumber], [SomeNumber], [SomeNumber], [SomeNumber], [SomeNumber], [SomeNumber], [SomeNumber], [SomeNumber] }
MEMBER SomeNumberSum AS
Round(SUM([SomeNumberSet], [Measures].[SomeNumber]) / 8, 2)
SELECT [SomeNumberSum] ON 0
FROM [SomeCube]
This code returns 0.59, the sum of sets are 4,76, which are then divided by 8 = 0,595. Since MDX is using Bankers rounding this SHOULD be rounded to 0.60.
Just using Round(0,595) gives us the correct result.
Whats even more strange is that if we in the set only uses the SomeNumber 6 times or less and in the Round Function divide with the same multiplier we get 0.6 (which is correct)
Also, if I wrap the Sum() with the StrToValue() function, it works, even if I use more than 5 SomeNumbers in the set
Whats going on?!
Not sure is the actual answer you're looking for. The issue you've has to do with numerical precision, aka rounding errors, more than with MDX.
If you're in Java, run the following test :
public void testNumeric()
{
double sum = 0.0;
double value = 0.595;
for (int i = 0; i < 8; i++)
{
sum += value;
}
double prod = value * 8;
assertEquals(sum / 8, prod / 8);
}
The assert will fail, strange no ?
Result : expected:<0.5949999999999999> but was:<0.595>
The first one, sum, is how mdx is calculating the value. You got a slight difference, but it is enough for changing the result of the ROUND().
Is there a solution ?
Strictly speaking no, it's an error due to the very nature of the numeric calculation with computers. Practically you can cheat a bit round first to 10 - ROUND(ROUND(MyNumber,10),2), not brillant (10 is an example).
If you're interested start in wikipedia from here
According with Chris Webb, this behaviour is intentional:
http://www.techonthenet.com/access/functions/numeric/round.php
If you have Excel libraries, this works:
WITH
MEMBER SomeNumber AS 0.595
SET SomeNumberSet AS
{[SomeNumber], [SomeNumber], [SomeNumber], [SomeNumber], [SomeNumber], [SomeNumber], [SomeNumber], [SomeNumber] }
MEMBER SomeNumberSum AS
Excel!Round(SUM([SomeNumberSet], [Measures].[SomeNumber]) / 8, 2)
SELECT [SomeNumberSum] ON 0
FROM [Adventure Works]
Related
i am running a complex calculation through update query, i managed to get all other work done however am struggling to get this bit done. i use function builder window to set the update fo field for the targeted field. My table is as following:
PHD_TAG
Cal_Value
Moisture
CO2_EF
CO2
ABC
100
0.5
0.45
*
FAC1
20
FAC2
7
My function is to calculate and update the CO2 Field with a *
(1-((DLookup("Cal_Value", "TempTbl", "PHD_TAG = 'FAC1'"))+[Moisture])/100)*(DLookup("Cal_Value", "TempTbl", "PHD_TAG = 'FAC2'"))*[CO2_EF]/(22.4*44*24)
the query generated in query builder "SQL Query" is as following:
UPDATE TempTbl SET TempTbl.CO2 = (1-((DLookUp("Cal_Value","TempTbl","PHD_TAG = 'FAC1'"))+[Moisture])/100)*(DLookUp("Cal_Value","TempTbl","PHD_TAG = 'FAC2'"))*[CO2_EF]/(22.4*44*24)
WHERE (((TempTbl.PHD_TAG)="ABC"));
i had the PHDTAG wrong and fixed it then i had to change the brackets to perform the proper mathematical calculation.
the expression used is correct just the PHD_TAG was wrong and the brackets in formula
I have successfully connected to my database, but when I select 2 cells from my SQL db to set the value for both of my variables it does nothing. I have no problem inserting data into the database. I have tried different approaches to this with no success. Could it be that I am trying to use a string format for doubles??
double userHeight;
double userWeight;
QSqlQuery query;
QString retreiveUserHeight =
QString("SELECT Height, Weight FROM SQL1 WHERE Username='joejoe'");
query.prepare(retreiveUserHeight);
query.bindValue(0,"Height");
query.bindValue(1, "Weight");
query.exec();
userHeight = query.value(0).toInt();
userWeight = query.value(1).toInt();
I'm pretty certain there is a small error in syntax that is causing this mishap but I have been unable to find it. Thanks for your help.
qDebug() << "calculated" << 703*(userWeight/(userHeight*userHeight))
<< userWeight << userHeight ;
Heres the debug output:
calculated nan 0 0
// Obtain username from somewhere
QString username = "joejoe";
// Check whether DB is open
if( db->isOpen( ) )
{
QSqlQuery query;
double userHeight;
double userWeight;
// Prepare select statement
query.prepare ( "SELECT Height , Weight FROM SQL1 WHERE Username = :username" );
query.bindValue ( ":username" , username );
query.exec ( );
// Check if something went wrong when executing your query
if( query.lastError( ).text( ).trimmed( ) == "" )
{
// Loop through all results and handle them accordingly
while( query.next( ) )
{
userHeight = query.value( 0 ).toDouble( );
userWeight = query.value( 1 ).toDouble( );
qDebug( ) << "calculated" << 703 * ( userWeight / ( userHeight * userHeight ) ) << userWeight << userHeight;
qDebug( ) << "---------------------------------";
}
}
else
{
// Display the error that occured
QMessageBox::critical( this , tr( "SQL Error" ) , query.lastError( ).text( ) );
}
}
I assume this is what you wanted it to look like.
I've included some error checking and corrected your query to use .bindValue( ) correctly, since it's not meant for using for return values rather than for input as seen in the WHERE.
Since I don't know anything about your sql table I've included a loop to go through all results of your query. That can obviously be changed.
Apart from that if you're using doubles you should cast the result .toDouble( ) rather than .toInt( )
There are a number of serious problems with this code. Let's start with the concept of prepared SQL queries. Wikipedia lists two reasons for using prepared statements:
The overhead of compiling and optimizing the statement is incurred
only once, although the statement is executed multiple times. [...]
Prepared statements are resilient against SQL injection, because
parameter values, which are transmitted later using a different
protocol, need not be correctly escaped.
Neither of these reasons apply in your code; you're only executing the query once, and you're not splicing any inputs into the string. In fact, the only input in your query at all is the username, which is hard-coded to "joejoe":
"SELECT Height, Weight FROM SQL1 WHERE Username='joejoe'"
Since there are no variable inputs, using a prepared query doesn't make much sense. Neither do the following lines:
query.bindValue(0,"Height");
query.bindValue(1, "Weight");
Height and Weight are outputs from this query, not inputs. See the section in the Qt docs for QSqlQuery titled "Approaches to Binding Values" for an explanation of how this is intended to work. Qt's API for binding prepared SQL queries is fairly typical among database libraries, there's nothing earth shattering here.
Then we get to this:
userHeight = query.value(0).toInt();
userWeight = query.value(1).toInt();
Both the variables you're reading into here were declared as doubles, but you're calling toInt() on the returned QVariant rather than toDouble(). I don't know what (if any!) values are in your database, but it's possible they're getting rounded down to zero during the conversion from double to int if the values are between -1.0 and 1.0.
That said, you aren't doing any error checking whatsoever. The methods prepare() and exec() return bools that indicate whether they succeeded or failed. Likewise, both toInt() and toDouble() tell you whether they've succeeded or failed if you pass in a pointer to a bool. It's worth noting that both methods also return a zero value on failure.
I have basic doubt.I have to convert float minutes =( (10.09/60 ) % 60);
but error is invalid to binary expression(double to double).
how can I make this calculation easy..
What I am trying is firstly
float minutes =( (10.09/60 )
then trying to convert minutes into NSInterger to solve module (%) operation..
but how can I do this...or else suggest other solution to get this calculation..
float minutes =( (10.09/60 ) % 60);
The % operator doesn't work on floating-point values. You'll have to use a function to calculate what you want. Here's the basic pseudocode of what it would look like:
B % A = B - (floor(B / A) * A)
There are also library functions which will do this for you in math.h or tgmath.h
Also, you can use:
fmod() or fmodf() from .
To use %, you have to use an int. So : (int)(10.09)%60 should work.
You can use following operations depends upon requirement
float myFloat = 3.333
//for nearest small integer:
int result = (int)ceilf(myFloat );
//for nearest big integer:
int result = (int)roundf(myFloat );
//for nearest integer:
int result = (int)floor(myFloat);
//For just an integer value
int result = (int) (myFloat);
I am working in MS WebMatrix using razor.
The issue I am having is that if one of my queries resolves to an error (dividing by 0, for instance) the whole page fails. I want the query to output "0" for this.
Code:
var itot = db.QueryValue("SELECT SUM(SUBTOTAL) from dbo.DR_TRANS where TRANSDATE = 41195 and SUBTOTAL >0");
var ctot = db.QueryValue("SELECT SUM(SUBTOTAL) from dbo.DR_TRANS where TRANSDATE = 41195 and TRANSTYPE = 1 and SUBTOTAL <0");
var nett = itot + ctot;
So, if either itot or ctot renders Null or error because there is no entries for the selected date, how do I get it to treat error as "0" so the math still works? In this example, itot is total invoices raised today, ctot is total credits raised today.
If there are no invoices yet, or if there are no credits raised yet, my code throws an error and shuts the page down. I want it to display 0 if there's none of either, and the value of itot if theres no ctot.
What am I doing wrong? it works fine the moment there's some of each, but I want it to work before that, because there's other code on the page for displaying other query results.
I'm very new to coding queries, so there will be a basic answer I have missed in my online searching!
Wrapping the aggregate function with COALESCE should return 0 rather than NULL:
SELECT COALESCE(SUM(SUBTOTAL), 0)
FROM dbo.DR_TRANS
WHERE TRANSDATE = 41195
AND SUBTOTAL >0
ie a function that returns the first parameter if it is not null, and the second parameter if the first is NULL. I don't know what function to use with webmatrix, but COALESCE is pretty standard. In Oracle, you could use NVL. ISNULL is another such function.
#Glenn offers a perfectly fine solution using SQL. However, you might prefer to understand how to deal with nulls in c#. The null-coalescing operator ?? which is a mouthful, says if something is not null, use it, and if it's null, use what's after the ??. An example is way easier to understand than what I just wrote. The last line of your code would look like:
var nett = itot ?? 0 + ctot ?? 0;
Basically the ?? 0 says if it's null, treat it as a zero, otherwise use the value itself.
I prefer to do as much as possible in c#, and keep my SQL as simple as possible. But I recognize that's more of a personal preference.
In general, there will be cases where you have to deal with nulls being returned by your SQL, perhaps a field where null means the user hasn't entered anything, and a zero means the user did enter a zero. In those case, you can test for null in your c#, like
if ( itot == null )
{
// do appropriate null stuff
itot = 0;
}
else
{
// do non null stuff
// nothing needed in this case
}
I need to find a maximum of the function:
a1^x1 * const1 + a2^x2 * const2 +....+ ak^xk * constk = qaulity
where xk>0 and xk is integer. ak is constant.
constraint:
a1^x1 * const1*func(x1) + a2^x2 * const2*func(x2) +....+ ak^xk * constk*func(xk) < Budget
Where func is a discrete function:
func(x)
{
switch(x)
{
case 1: return 423;
case 2: return 544;
...
etc
}
}
k may be big(over 1000). x less then 100.
What is the best method?
There are techniques like nelder-mead optimization (which I believe GSL implements), but most techniques assume some sort of special structure (i.e. convexity or continuity). Depending on the values of the function, there may not exist a unique optimum or even an optimum that a normal downhill method can find.