I try to perform arithmetic functions on a table in mysql database. on the table there are 5 field where the first field is the primary key and other fields is an integer data type.
Assume a field that has a data type is integer W, X, Y, and, Z. I want to do the calculation by the following formula:
(Xi - Xavg)^2
Xi = value of record i
Xavg = average value of field X
I write my query like this:
SELECT W, X, Y, Z, POW(W - AVG(W),2), POW(X - AVG(X),2), POW(Y - AVG(Y),2), POW(Z - AVG(Z),2)
FROM nilai
And here the result:
But the result only showing the first record. is there any way, so i can display all the records and the results of the calculations?
Related
I am new to mysql I need to get the sum of columns but could not get in single command
I have a table of
Name, Class, zone1,zone2,zone3,zone4
X, 1, 10,20,30,40
X, 2, 50,60,70,80
Y, 1, 20,30,40,50
Y, 3, 70,80,90,10
I need a single mysql command to get the sum of zone1 to zone4 per name and class
X,1,Sum
X,2,Sum
Y,1,Sum
Y,3,sum.
... etc
I tried select
(Thanks I have modified query to )
select Name,Class,zone+zone2+zone3+zone4 as Total from table;
Now how to get the result as (though i can do in php, but any method to do in mysql itself)
X,1,Sum,2,Sum
Y,1,Sum,3,sum
... etc
Chnage your query to select Name,Class,(zone+zone2+zone3+zone4) as Total from table; and try again
I am working on an application that requires me to validate if 3 randomly generated numbers match a 3 digit string that has been entered into a database from user input. I also need to preserve the exact order that the user enters the string, so sorting on input is not an option.
For example, the randomly generated digits may be 6 4 0, and in the database a string may show as '406'.
Is there an easy way this can be accomplished in a single query without enumerating the options or adding an extra column/view?
maybe you could try
create table y (z varchar(10));
insert into y values ('406');
insert into y values ('604');
insert into y values ('446');
insert into y values ('106');
insert into y values ('123');
and then
SELECT * from y where FIND_IN_SET(Substring('640',1,1),MAKE_SET(7,Substring(z,1,1),Substring(z,2,1),Substring(z,3,1))) and FIND_IN_SET(Substring('640',2,1),MAKE_SET(7,Substring(z,1,1),Substring(z,2,1),Substring(z,3,1))) and FIND_IN_SET(Substring('640',3,1),MAKE_SET(7,Substring(z,1,1),Substring(z,2,1),Substring(z,3,1)));
returns
406
604
Sum the three random digits
Something like
Select * From Triplets Where (Ascii(Substring(Number,0,1)) - 48) + (Ascii(substring(Number,1,1)) -48) +
(Ascii(substring(Number,2,1)) -48) = MySumOfNumber
easy is a state of mind isn't it, Storage requirement of an extra "CheckSum" int, versus the high cost of a query like this.
Trying to wrap my head around how to do this query - I want to return a list of client records and need to exclude clients if they had only a specific value and no other values.
For example
c# value
1 X
1 Y
2 X
3 Y
I want all the records for clients 1 and 3, since they had a value other than X. I do not want client 2, because that client had ONLY X.
I for example want returned in this case:
1 X
1 Y
3 Y
Of course, I could have lots of other records with other client id's and values, but I want to eliminate only the ones that have a single "X" value and no other values.
Maybe using a sub-query?
Try this:
SELECT client, value FROM myTable where `client` in
(select distinct(client) from myTable where value !='X');
Returns:
Client Value
1 X
1 Y
3 Y
Something like this
SELECT ABB2.*
FROM
mytable AS ABB2
JOIN
(SELECT c
FROM mytable
WHERE value <> "X"
GROUP BY c) AS ABB1 ON ABB1.c = ABB2.c
GROUP BY ABB2.c, ABB2.value
It's faster than using a WHERE clause to identify the sub query results (as in Mike's answer)
I've been using a pretty simple array formula in excel to crunch some datasets but they're getting too large and absolutely destroying my computers performance whenever I update the calculations.
The excel sheet and MySQL database are laid out like so:
+-Timestamp-+-value-+
| 1340816430| .02 |
---------------------
x600,000 rows
Here's the excel formula:
{=AVERAGEIFS(B:B,A:A,"<"&A1+1000,A:A,">"&A1-1000)}
That returns the average of the values, and is the third column in the excel sheet. Is there any plausible way for me to create a MySQL query that performs a similar operation and returns a column with the values that would have been in the third column had I run excel's formula?
If you are happy using Excel formulas you can speed up this calculation a lot (factor of over 3000 on my system). Assuming that Column A contains the timestamps in ASCENDING ORDER and Column B the values (if not already sorted then use Excel Sort).
in Column C put =IFERROR(MATCH(A1-1000,$A:$A,1),1) and copy down. This calculates the row number of the row 1000 timestamp less.
in Column D put =IFERROR(MATCH(A1+1000,$A:$A,1),1048576) and copy down. This calculates the row number of the row 1000 timestamp more.
in column E put =AVERAGE(OFFSET(B1,C1-ROW(),0,D1-C1+1,1)) and copy down. This calculates the average of the subset range from the first row to the last row. On my system this full calculates 1000K rows in 20 seconds. The disadvantage of this method is that its volatile so will recalculate whenever you make a change, but I assume that you are in Manual calculation mode anyway.
MySQL code:
select
a.timestamp t1,
avg(x.value) average_value
from
mydata a inner join (
select
timestamp,
value
from mydata
) x
on x.timestamp between a.timestamp - 1000 and a.timestamp + 1000
group by
a.timestamp
order by
t1
;
I would like to think that without the Excel overhead this will perform far better, but I can't promise it will be lightning fast on 600k rows. You will definitely want to index Timestamp. See also SQL Fiddle I created.
#Peter You can stick with Excel if you want to. Just use http://xllarray.codeplex.com. The formula you want is =AVERAGE(ARRAY.MASK((A:A>A1 + 1000)*(A:A<A1 - 1000), B:B). 1MM rows on my junky laptop calculate in under 1 second. Be sure to Ctrl-Shift-Enter it as an array formula.
If you don't want to build the code, you can grab the add-in and help file off my SkyDrive: http://sdrv.ms/JtaMIV
#Charles. Ah, no. It is only for one formula. Misread the spec.
If you wanted to push the calculation into C++ and expose it as an xll, here is how you might do that:
#include <algorithm>
#include <numeric>
#include "xll/xll.h"
using namespace xll;
typedef traits<XLOPER12>::xword xword;
static AddIn12 xai_windowed_average(
L"?xll_windowed_average", XLL_FP12 XLL_FP12 XLL_FP12 XLL_DOUBLE12,
L"WINDOWED.AVERAGE", L"Time, Value, Window"
);
_FP12* WINAPI
xll_windowed_average(_FP12* pt, _FP12* pv, double dt)
{
#pragma XLLEXPORT
static xll::FP12 a(size(*pt), 1);
double* bt0 = &pt->array[0];
double* bv0 = &pv->array[0];
double* bt = std::lower_bound(begin(*pt), end(*pt), *bt0 - dt);
double* et = std::lower_bound(begin(*pt), end(*pt), *bt0 + dt);
for (xword i = 0; i < size(*pt); ++i) {
a[i] = (bt == et) ? 0 : std::accumulate(bv0 + (bt - bt0), bv0 + (et - bt0), 0)/(et - bt);
// update the window
bt = std::lower_bound(bt, end(*pt), pt->array[i] - dt);
et = std::lower_bound(bt, end(*pt), pt->array[i] + dt);
}
return a.get();
}
I have a table called ORDEREXECUTIONS that stores all orders that have been executed. It's a multi currency application hence the table has two columns CURRENCY1_ID and CURRENCY2_ID.
To get a list of all orders for a specific currency pair (e.g. EUR/USD) I need to lines to get the totals:
v = Orderexecution.where("is_master=1 and currency1_id=? and currency2_id=? and created_at>=?",c1,c2,Time.now()-24.hours).sum("quantity").to_d
v+= Orderexecution.where("is_master=1 and currency1_id=? and currency2_id=? and created_at>=?",c2,c1,Time.now()-24.hours).sum("unitprice*quantity").to_d
Note that my SUM() formula is different depending on the the sequence of the currencies.
e.g. If I want the total ordered quantities of the currency pair USD it then executes (assuming currency ID for USD is 1 and EUR is 2.
v = Orderexecution.where("is_master=1 and currency1_id=? and currency2_id=? and created_at>=?",1,2,Time.now()-24.hours).sum("quantity").to_d
v+= Orderexecution.where("is_master=1 and currency1_id=? and currency2_id=? and created_at>=?",2,1,Time.now()-24.hours).sum("unitprice*quantity").to_d
How do I write this in RoR so that it triggers only one single SQL statement to MySQL?
I guess this would do:
v = Orderexecution.where("is_master=1
and ( (currency1_id, currency2_id) = (?,?)
or (currency1_id, currency2_id) = (?,?)
)
and created_at>=?"
,c1, c2, c2, c1, Time.now()-24.hours
)
.sum("CASE WHEN currency1_id=?
THEN quantity
ELSE unitprice*quantity
END"
,c1
)
.to_d
So you could do
SELECT SUM(IF(currency1_id = 1 and currency2_id = 2, quantity,0)) as quantity,
SUM(IF(currency2_id = 1 and currency1_id = 2, unitprice * quantity,0)) as unitprice _quantity from order_expressions
WHERE created_at > ? and (currency1_id = 1 or currency1_id = 2)
If you plug that into find_by_sql you should get one object back, with 2 attributes, quantity and unitprice_quantity (they won't show up in the output of inspect in the console but they should be there if you inspect the attributes hash or call the accessor methods directly)
But depending on your indexes that might actually be slower because it might not be able to use indexes as efficiently. The seemly redundant condition on currency1_id means that this would be able to use an index on [currency1_id, created_at]. Do benchmark before and after - sometimes 2 fast queries are better than one slow one!