Related
Example input:
3 4
10 20 30
40 10 30
20 10 0
5 15 5
Example output:
1 3
2 1
4 2
85
30 + 40 + 15 = 85
I need get the result of a matrix with thousand rows and columns
Each row Total value go for the set OP value for the next row, except the first row
My Table Data
Id
WarehouseId
ProductId
OP
RE
IS
Total
1
100
10000
10
0
0
10
2
100
10000
0
0
5
5
4
100
10000
0
15
0
15
5
101
10001
15
0
0
15
6
101
10001
0
0
5
5
8
101
10001
0
15
0
15
9
101
10002
25
0
0
25
10
101
10002
0
0
10
10
11
101
10002
0
15
0
15
I want to show below result (OP+RE)-IS=Total
Id
WarehouseId
ProductId
OP
RE
IS
Total
1
100
10000
10
0
0
10
2
100
10000
10
0
5
5
4
100
10000
5
15
0
20
5
101
10001
15
0
0
15
6
101
10001
15
0
5
10
8
101
10001
10
15
0
25
9
101
10002
25
0
0
25
10
101
10002
25
0
10
15
11
101
10002
15
15
0
30
You can use recursive subquery factoring for that purpose like below. You need to rank your data as you have some gaps between IDs in your data. Column name = IS is not allowed, You should use "IS" enclosed by ".
with t1 ( ID, WAREHOUSEID, PRODUCTID, OP, RE, "IS", RNB, rnb_per_wh_prod) as (
select ID, WAREHOUSEID, PRODUCTID, OP, RE, "IS"
, row_number()over(order by WAREHOUSEID, PRODUCTID, ID) rnb
, row_number()over(partition by WAREHOUSEID, PRODUCTID order by ID) rnb_per_wh_prod
from Your_table t
), cte (ID, WAREHOUSEID, PRODUCTID, OP, RE, "IS", Total, RNB) as (
select ID, WAREHOUSEID, PRODUCTID, OP, RE, "IS", OP + RE - "IS", RNB
from t1
where rnb_per_wh_prod = 1
union all
select t1.ID
, t1.WAREHOUSEID
, t1.PRODUCTID
, case when t1.op = 0 then c.OP + c.RE - c."IS" else t1.OP end as OP
, t1.RE
, t1."IS"
, case when t1.op = 0 then c.OP + c.RE - c."IS" else t1.OP end + t1.RE - t1."IS" total
, t1.RNB
from cte c
join t1 on (t1.RNB = c.RNB + 1
and c.WAREHOUSEID = t1.WAREHOUSEID
and c.PRODUCTID = t1.PRODUCTID)
)
select ID, WAREHOUSEID, PRODUCTID, OP, RE, "IS", TOTAL
from cte
order by id
;
If I understand the problem correctly, "every 3 row" is a coincidence in your data; in fact, the computation must be done separately for each product in each warehouse, no matter how many rows there are for each distinct combination. And the "id" column is in reality some sort of timestamp - ordering is by "id".
If so, you can do it all in a single query using analytic sum(). Instead of creating a table for testing, I included all the sample data in a WITH clause at the top of the query itself; you can remove the WITH clause, and use your actual table and column names. I also changed the column name is to is_ since is is a reserved keyword, it can't be a column name.
Note also that I am ignoring your existing total column completely (I didn't even include it in the sample data); I assume it doesn't exist in your real-life data, and instead it is part of your attempt at a solution. You don't need it - not in the way you have it in your question.
with
sample_data (id, warehouseid, productid, op, re, is_) as (
select 1, 100, 10000, 10, 0, 0 from dual union all
select 2, 100, 10000, 0, 0, 5 from dual union all
select 4, 100, 10000, 0, 15, 0 from dual union all
select 5, 101, 10001, 15, 0, 0 from dual union all
select 6, 101, 10001, 0, 0, 5 from dual union all
select 8, 101, 10001, 0, 15, 0 from dual union all
select 9, 101, 10002, 25, 0, 0 from dual union all
select 10, 101, 10002, 0, 0, 10 from dual union all
select 11, 101, 10002, 0, 15, 0 from dual
)
select id, warehouseid, productid,
nvl(sum(op + re - is_) over (partition by warehouseid, productid
order by id rows between unbounded preceding and 1 preceding),
op) as op,
re, is_,
sum(op + re - is_) over
(partition by warehouseid, productid order by id) as total
from sample_data
;
ID WAREHOUSEID PRODUCTID OP RE IS_ TOTAL
------ ----------- ---------- ---------- ---------- ---------- ----------
1 100 10000 10 0 0 10
2 100 10000 10 0 5 5
4 100 10000 5 15 0 20
5 101 10001 15 0 0 15
6 101 10001 15 0 5 10
8 101 10001 10 15 0 25
9 101 10002 25 0 0 25
10 101 10002 25 0 10 15
11 101 10002 15 15 0 30
What is ** operator in Ruby?
Code snippet
1 ** 5 # => 1
43 ** 67 # => 27694053307656599023809257877241042019569010395053468294153499816223586030238186389799480520831161107426185107
In Ruby, ** is the exponent operator. I.e., by doing a**b, you are raising a to the power of b. By convention, there are no spaces between the operands.
Example:
3**2
#=> 9
2**3
#=> 8
Note that the exponent operator has a higher precedence than multiplication and division, just like in mathematics:
2 * 2**3 # (2 * 8)
#=> 16
18 / 3**2 # (18 / 9)
#=> 2
If you chain the operator, precedence is resolved from the right to the left:
2**2**3 == 2**(2**3) # (2^8)
#=> true
It's a power math operator:
2 * 3
# => 6
but
2 ** 3
# => 8
** is Exponent Operator- It performs exponential (power) calculation. Let me explain by this simple example
2 ** 2 => 2 * 2 => 4
2 ** 3 => 2 * 2 * 2 => 8
2 ** 4 => 2 * 2 * 2 * 2 => 16
2 ** 5 => 2 * 2 * 2 * 2 * 2 => 32
so 43 ** 67 => 43 * 43 * 43 * 43 ...............................................................
so it results in such a big number.
To get more details on operatorts http://www.tutorialspoint.com/ruby/ruby_operators.htm
** Exponent - Performs exponential (power) calculation on operators
1 ** 5 = 1
Means it will execute like 1*1*1*1*1 five times
If you will try this
2**4 = 16
Means it will execute like 2*2*2*2 four times
Its just do it as:
2 * 4 => 8
and
2 ** 4 => 64
It treat as power of 2 as (2)^4 => 2*2*2*2
So, pondering the X/Y of it all, I guess the real question here is- how DO you store data for a logic puzzle like this one? (Scroll to the bottom for a link to the puzzle.) I have chosen this hash, where every piece of the puzzle gets its own key + 5 offsets which can be marked T, F or nil. I am using 9 for nil because I can add 9, and the logic I am using leans on simple math.
I need to check seven values, and if all of them are a certain way, I then go set some other values. This check runs three times- it cycles through the three positions where the set of four nines and three zeros can appear
Here's my hash- in actual use, it starts out all nines, 9 = null, 1 = true, 0 = false
$l1 = {
1 => [9,9,9,9,9], 2 => [9,9,9,9,9], 3 => [ , ,9, ,0], 4 => [ , , , ,0], 5 => [ , , , ,0],
6 => [9,9,9,9,9], 7 => [9,9,9,9,9], 8 => [ , ,9, ,9], 9 => [ , ,9, ,0], 10 => [ , , , ,0],
11 => [9,9,9,9,9], 12 => [9,9,9,9,9], 13 => [ , , , ,9], 14 => [ , ,9, ,9], 15 => [ , ,9, ,0],
16 => [9,9,9,9,9], 17 => [9,9,9,9,9], 18 => [ , , , ,0], 19 => [ , , , ,9], 20 => [ , ,9, ,9],
21 => [9,9,9,9,9], 22 => [9,9,9,9,9], 23 => [ , , , ,0], 24 => [ , , , ,0], 25 => [ , , , ,9]}
Shown here as an example, the three instances of the pattern we are checking for appear in the 3rd, 4th, and 5th columns. I have removed the other values so you can see it better.
The pattern itself should appear in the second column, [2,7,12,17,22].
Here's the first iteration of the check using &&:
if $l1[2][2] == 9 && $l1[7][2] == 9 && $l1[7][4] == 9 && $l1[12][4] == 9 && $l1[2][4] == 0 && $l1[17][4] == 0 && $l1[22][4] == 0
$l1[7][0] = 0
$l1[7][1] = 0
$l1[7][3] = 0
end
I also tried it with seven nested if statements, and it just stops matching two or three steps in even though the pattern is a perfect match.
How else can you check something like this? Thanks in advance for any help!
EDIT: expanding the explanation- I have zero formal training in programming other than a few courses at codecademy. I am building logic to solve the "Whose Fish?" puzzle, http://www.coudal.com/thefish.php , and this puzzle goes something like this-
There are five men, from five countries, living in a row in five different colored houses, they smoke different brands, drink different drinks, and have different pets.
There are 15 clues and no way to solve this without a pencil and paper or a spreadsheet... my goal is to make logic which solves the puzzle withOUT making any intuitive leaps myself- they have to be coded into the program. Clues + logic either solve it, or I need to re-tune the logic.
I have a lot of the logic built already, but the specific logic for this special clue "the green house is on the left of the white house" is proving pretty difficult to build.
I didn't want to mire eveyone down in a very long story, but it looks unavoidable...
So yes, the data all being stored in one hash like this is possibly counter-intuitive, but it's all I could come up with for data storage that I could figure out how to easily dump out and view to debug, and it's easy to look at for me as a beginner, and I have already switched it from five separate hashes- one for each man- because I ran into problems understanding how to build the logic when there were five hashes. Thanks again for looking into this with me.
Well, I do not know why it is working now, but I took my three nested passes and made them into their own methods, and it's working right.
Before it was like this:
if X == 1
if Y == 2
if Z == 3
Q = 0
end
end
elsif X == 2
if Y == 3
if Z == 4
Q = 1
end
end
end
Now it's like this
def first
if X == 1
if Y == 2
if Z == 3
Q = 0
end
end
end
end
def second
if X == 2
if Y == 3
if Z == 4
Q = 1
end
end
end
end
I have the following problem - made abstract to bring out the key issues.
I have 10 points each which is some distance from the other. I want to
be able to find the center of the cluster i.e. the point for which the pairwise distance to each other point is minimised,
let p(j) ~ p(k) represent the pairwise distance beteen points j and k
p(i) is center-point of the cluster iff p(i) s.t. min[sum(p(j)~p(k))] for all 0 < j,k <= n where we have n points in the cluster
determine how to split the cluster in to two clusters once the number of data points in the cluster goes above some threshold t.
This is not euclidean space. But the distances can be summarised as follows - p(i) is point i:
p(1) p(2) p(3) p(4) p(5) p(6) p(7) p(8) p(9) p(10)
p(1) 0 2 1 3 2 3 3 2 3 4
p(2) 2 0 1 3 2 3 3 2 3 4
p(3) 1 1 0 2 0 1 2 1 2 3
p(4) 3 3 2 0 1 2 3 2 3 4
p(5) 2 2 1 1 0 1 2 1 2 3
p(6) 3 3 2 2 1 0 3 2 3 4
p(7) 3 3 2 3 2 3 0 1 2 3
p(8) 2 2 1 2 1 2 1 0 1 2
p(9) 3 3 2 3 2 3 2 1 0 1
p(10) 4 4 3 4 3 4 3 2 1 0
How would I calculate which is the center point of this cluster?
As far as I understand this looks like K Means Clustering, and what you are looking for is usually known as 'Medoids'.
See here: http://en.wikipedia.org/wiki/Medoids or here: http://en.wikipedia.org/wiki/K-medoids
I may be about to have that frisson that comes just before displaying utter stupidity. But doesn't this yield easily to brute force? In Python:
distances = [
[ 0 , 2 , 1 , 3 , 2 , 3 , 3 , 2 , 3 , 4 , ],
[ 2 , 0 , 1 , 3 , 2 , 3 , 3 , 2 , 3 , 4 , ],
[ 1 , 1 , 0 , 2 , 0 , 1 , 2 , 1 , 2 , 3 , ],
[ 3 , 3 , 2 , 0 , 1 , 2 , 3 , 2 , 3 , 4 , ],
[ 2 , 2 , 1 , 1 , 0 , 1 , 2 , 1 , 2 , 3 , ],
[ 3 , 3 , 2 , 2 , 1 , 0 , 3 , 2 , 3 , 4 , ],
[ 3 , 3 , 2 , 3 , 2 , 3 , 0 , 1 , 2 , 3 , ],
[ 2 , 2 , 1 , 2 , 1 , 2 , 1 , 0 , 1 , 2 , ],
[ 3 , 3 , 2 , 3 , 2 , 3 , 2 , 1 , 0 , 1 , ],
[ 4 , 4 , 3 , 4 , 3 , 4 , 3 , 2 , 1 , 0 , ],
]
currentMinimum = 99999
for point in range ( 10 ) :
distance_sum = 0
for second_point in range ( 10 ) :
if point == second_point : continue
distance_sum += distances [ point ] [ second_point ]
print '>>>>>', point, distance_sum
if distance_sum < currentMinimum :
currentMinimum = distance_sum
centre = point
print centre
a)
find median or average values of all distances. = avgAll
For each p, find average distance to other machines. = avgP(i)
Pick the closer one as center. avgAll ~= avgP(i)
b)
no idea for now..
maybe for each p, find the closer machine.
by this logic make a graph.
than somehow (i dont know yet) divide the graph
What you're trying to do, or at least (b) belongs to Cluster Analysis. A branch of mathematics / statistics / econometrics where datapoints (e.g. points in n-dimensional space) are divided among groups or clusters. How to do this is not a trivial questions, there are many, many possible ways.
Read more at the wikipedia article on cluster analysis.