how to fix query mysql with multiple sum - mysql

I have a query data from sum function:
ROUND(((nominal)*12) * ROUND((SUM((a.NCI)/3*(60/100))+SUM((b.NSI)/3*(40/100)))/3,2)/100,2) AS nominal_persentasi,
ROUND((((nominal)*12) * ROUND((SUM((a.NCI)/3*(60/100))+SUM((b.NSI)/3*(40/100)))/3,2))*(1.1/100)/100,2) AS tambah_persentasi,
ROUND((((nominal)*12) * ROUND((SUM((a.NCI)/3*(60/100))+SUM((b.NSI)/3*(40/100)))/3,2))+((((nominal)*12) * ROUND((SUM((a.NCI)/3*(60/100))+SUM((b.NSI)/3*(40/100)))/3,2))*(1.1/100))/100,2) AS total_penyesuaian
And the results are:
nominal_persentasi | tambah_persentasi | total_penyesuaian
12.000 3.000 1.203.000
The results produced should be 15,000 , why did it happen ?
I tried to sum the variable nominal_persentasi + tambah_persentasi but the result is 0.

You are missing a division by 100 in your total. Hence, instead of adding 12,000 and 3,000 to get 15,000 you were actually adding 12,000,000 and 3,000 to get 12,003,000.
SELECT ROUND(( (nominal)*12) * ROUND((SUM((a.NCI)/3*(60/100))+SUM((b.NSI)/3*(40/100)))/3,2)/100,2) AS nominal_persentasi,
ROUND((((nominal)*12) * ROUND((SUM((a.NCI)/3*(60/100))+SUM((b.NSI)/3*(40/100)))/3,2))*(1.1/100)/100,2) AS tambah_persentasi,
ROUND((((nominal)*12) * ROUND((SUM((a.NCI)/3*(60/100))+SUM((b.NSI)/3*(40/100)))/3,2)/100) + ((((nominal)*12) * ROUND((SUM((a.NCI)/3*(60/100))+SUM((b.NSI)/3*(40/100)))/3,2))*(1.1/100))/100, 2) AS total_penyesuaian
FROM yourTable -- your query was missing this division by 100 ^^^

Related

GCP Bigquery, I want to aggregate some values by a catogrical value in one column

I have these data that I want to analyze, schema as follows
timestamp price volume Qualifiers TradeCatogary
------------------- ----- ------ ---------- -------------
2016-07-11 01:00:00 3 2323 U OML
2016-07-11 01:02:03 2.5 434 K KCL
2016-07-11 01:03:34 4 3244 U KCL
2016-07-11 01:23:00 2.3 45 K OML
...
What I want is to calculate the total share, value of trade, trade count, and average price(VWAP = dollarTraded / totalVolume) of each 5min. Desired schema as follows
timestamp tradeCount totalVolume dollarTraded VWAP
--------- ---------- ----------- ------------ ----
This isn't hard and I managed it with SQL like this
SELECT
TIMESTAMP_SECONDS(CAST((ROUND(UNIX_SECONDS(Date_Time) / 300) * 300) AS int64)) AS interval_alias1,
count(*) AS cnt,
SUM(Volume) AS ShareVolumeTraded,
SUM(Price * Volume) AS DollarVolumeTraded,
(SUM(Price * Volume) / SUM(Volume)) AS VWAP
FROM
`dbd-sdlc-prod.HKG_NORMALISED.HKG_NORMALISED`
WHERE
RIC = '1606.HK'
AND Type="Trade"
AND (Date_Time BETWEEN TIMESTAMP('2016-07-11 00:00:00.000000') AND
TIMESTAMP('2016-07-11 23:59:59.999999'))
AND Volume >0
AND Price >0
GROUP BY
ROUND(UNIX_SECONDS(Date_Time) / 300), interval_alias1
ORDER BY interval_alias1
However, I want to push my analyze a bit further, I want not just a total summary of trades, I'd like to have more specific analyze based on different combination of qualifiers and tradeCatogary, such as:
count_U volume_U dollar_U VWAP_U count_U_OML volume_U_OML dollar_U_OML VWAP_U_OML ....
there are two qualifiers and two catogaries in the example so there will be:
3(basic) + 2 * 3(only qualifier) + 3 * 2 * 2(qualifier and catogary combination) = 21 columns
If there are no such trade in these time slot, the value will be left 0 as default
I wish to manage these queries with one SQL execution, I'm not sure how to address it, please give me a hint or some, thanks in advance
As mentioned in the comments, Group By Rollup is appropriate for your case. Group By Rollup returns the results of Group By on all possible combinations of mentioned columns. Since you also want the output as columns rather than rows, you can use pivot tables to change rows to columns. Also for your other requirement i.e. to concatenate the outputs of two columns and make it as a single column, CONCAT function can be used.

Creating buckets to categorize the values using MySQL

Hi I am trying to create a buckets for a very large number of rows. I have a maximum value of 9759721 and a minimum value of 1006909. I would like to show the results as following:
distance
bucket
range
1006909
0
1000000 - 1009999
1013525
1
1010000 - 1019999
1021948
2
1020000 - 1029999
The table might not be so clear but in general, I would like to break down them by a change of 10000. Creating a new bucket once every 10000 starting from 1000000.
I tried the following code but it doesn't show the correct output.
select distance,floor(distance/10000) as _floor from data;
I got something like:
distance
bucket
1006909
100
1013525
101
1021948
102
1035472
103
1042069
104
9759721
975
This seems to be correct but I need the bucket to start from 0 and then change based on 10000. And then have a range column as well. The minimum value that I have for distance is 1006909 and so the data doesn't start with 0 but is it possible to still have a bucket column starting from 0 [i.e assigned to minimum distance].
SELECT
d.distance,
DENSE_RANK() OVER (ORDER BY d._floor) - 1 AS bucket,
d._floor * 10000 AS bucket_lower_limit,
d._floor * 10000 + 10000 AS bucket_upper_limit
FROM
(
SELECT
distance,
FLOOR(distance / 10000) AS _floor
FROM
data
)
AS d
NOTE: the will give buckets numbered from 0 upwards, but will also remove all gaps (such that you sample data will have bucket 5 for the last row, not bucket 975)
Alternatively, if you need to preserve the gaps...
SELECT
d.distance,
d._floor - MIN(d._floor) OVER () AS bucket,
d._floor * 10000 AS bucket_lower_limit,
d._floor * 10000 + 10000 AS bucket_upper_limit
FROM
(
SELECT
distance,
FLOOR(distance / 10000) AS _floor
FROM
data
)
AS d
Just calculate 1006909 div 10000 * 10000 = 1000000 and subtract it from distance. That'll make the buckets start from 0:
SELECT distance
, (distance - a) div 10000 AS bucket
, distance div 10000 * 10000 AS range_from
, distance div 10000 * 10000 + (10000 - 1) AS range_to
FROM t
CROSS JOIN (
SELECT MIN(distance) div 10000 * 10000 AS a
FROM t
) AS x
SQL Fiddle

How to get Random of two specific numbers?

E.g.
The first number is: 429
The second number is: 529
So I want to write MySQL query in such a way that, it should give me either 429 or 529 exactly.
I searched on google regarding this, but its showing results for a random number as a range.
Any help will be appreciated.
EDIT
My real requirement is this:
INSERT INTO table1(table2_id, status, stage, added_by)
(SELECT id, 'Pending', 'Semifinal', RAND(SELECT 429 UNION SELECT 529) FROM table2)
SELECT * FROM (SELECT 429 UNION SELECT 529) AS tmp ORDER BY RAND() LIMIT 1
Steps:
Select 429 and 529
Apply random order
Return first result
The function is the following (without UNION and ORDER, only math and only one step):
(ROUND(RAND()) * 100) + 429
or
(FLOOR(0 + (RAND() * 2)) * 100) + 429
Refer to MySQL docs
APPENDED
To give a general answer to the question (to select one random integer from any two integers :x and :y):
(FLOOR(0 + (RAND() * 2)) * (:y - :x)) + :x
This way does not create a mem table and does not sort the rows in it and/or fetch one of the random rows.
Is this data placed within a table? Then something like this might work:
SELECT number FROM table ORDER BY rand() LIMIT 1

Find number of items left based upon credit's id and all ids prior

I have a t variable which contains 100 and one table .
that table name credit and it contains the following data
Id
1
2
3
I would like the result set to look like this:
result
99 (100 - 1)
97 (100 - 2 - 1)
94 (100 - 3 - 2 - 1)
So far, I have been able to use the following code successfully:
set #t=100;
select #t:=#t-id as result from credit;
Is there a way to do this without using a variable?
This is quite simple and you shouldn't have to use the variable at all:
SELECT 100-(SELECT SUM(c2.id) FROM credit c2 WHERE c2.id <= c.id)
FROM credit c;
Here is a SQL Fiddle for you:
http://sqlfiddle.com/#!9/1fc3c6/6
The subquery simply gets the sum of all numbers including, and prior to the credit id.

How to compute the standard deviation with a "number" column?

I have this table in MySQL :
value number_ads
1 3
2 1
3 1
3 1
4 1
I would like to compute the standard deviation of the column value, but taking into account that the value 1 for example should be counted 3 times.
The result should be :
AVG = 2.1429 STD = 1.124858267715973
I tried with this following request, but I don't have the good result:
SELECT
SUM(value * number_ads) / SUM(number_ads) AS avg,
SQRT((SUM(POW(value, 2)) - POW(2.1429, 2))/SUM(number_ads))
FROM `test`
Calculate the square root of variance. Variance is the difference between mean of (squares of values) and square of mean i.e, Sum(xx)/Count(n) - MeanMean.
SELECT
SUM(value * number_ads) / SUM(number_ads) AS avg,
SQRT((SUM(POW(value ,2) * number_ads)/SUM(number_ads)) - avg * avg)
FROM `test`
Source