How to add an iterative id column which goes up when a value in another column resets to 1 in Postgresql - postgresql

I have a SQL table which has two columns called seq and sub_seq as seen below. I would like to add a third column called id, which goes up by 1 every time the sub_seq starts again at 1 as shown in the table below.
seq
sub_seq
id
1
1
1
2
2
1
3
3
1
4
4
1
5
5
1
6
1
2
7
2
2
8
3
2
9
1
3
10
2
3
11
3
3
12
4
3
13
5
3
14
6
3
15
7
3
I could write a solution using plpgsql, however I would like to know if there is a way of doing this in standard SQL. Any help would be greatly appreciated.

If sub_seq is always a running sequence then you can use the DENSE RANK function and order over the differences of two columns, assuming it will consistently uniform.
SELECT seq, sub_Seq, DENSE_RANK() OVER (ORDER BY seq-sub_Seq) AS id
FROM tableDemo
This solution is based on the sample data you have provided, I think more sample data would be helpful to check the whole scenario.

Related

Running total using two columns

Given a table with data like:
A
B
Qty.
Running Total
5
5
5
10
5
15
I can create the running total using the formula =SUM($A$2:A2) and then drag down to get the running total after each quantity (here Qty.)
What may I do for calculating running total using two columns which may or may not be consecutive as shown below:
A
B
C
D
Qty. 1
Other
Qty. 2
RT
2
blah
2
4
2
phew
2
8
3
xyz
2
13
Place in cell D2 the formula =SUM(A2,C2,D1). Do not pay attention to the fact that the function will refer to a non-numeric cell D1 - the SUM() function will not break, unlike ordinary addition =A2+C2+D1. Now, just stretch the formula down.

Count the number of membership changes across multiple vectors

I have 2 vectors in which elements of a similar value are considered to be of the same group, something like this:
V1 V2
1 7
1 8
1 8
1 8
1 9
2 10
3 11
3 11
3 11
3 12
4 12
4 12
In this example, V1 has 4 groups, group 1 has the first 5 elements , group 2 has the next 1 element, group 3 has the next 4 elements, and group 4 has the last 2 elements. V2 has 5 groups, group 1 has the first element, group 2 has the next 3 elements, etc.
Now, I would like to count the number of time an element switches groups, using V1 as the reference. Let's consider group 1 in V1. The first 5 elements are in this same group. In V2, that's no longer the case because V2(1,1) and V2(5,1) do not have the same value as the remaining elements and thus are considered to have switched/changed membership. Applied the same principle, there is no switch for group 2 (i.e.,V1(6,1) and V2(6,1)), one switch for group 3, and no switch for group 4. Total is 3 switches.
At first I thought this would be a simple calculation with no. of switches = numel(unique(V1)) - numel(unique(V2)). However, as you can see, this underestimates the number of switches. Does anyone have a solution to this?
I also welcome a solution to a simpler problem in which V1 contains only one group, like this:
V1 V2
2 7
2 8
2 8
2 8
2 8
2 8
2 8
2 9
2 8
2 10
2 10
2 8
In this second case, the count is 4 nodes that switch: V2(1,1), V2(8,1), V2(10,1), V2(11,1).
Side note: this is actually a network problem: V1 and V2 are partitions and I'm trying to count the number of time a node switches membership.
Here is a solution using unique and accumarray
u = unique([V1 V2],'rows');
switches = accumarray(u(:,1) , 1, [],#numel)-1;
total_switches = sum(switches)
or you can use histcounts
u = unique([V1 V2],'rows');
switches = histcounts(u(:,1) , [unique(u(:,1)); u(end,1)])-1;
total_switches = sum(switches)

How to find out if numbers are different in pascal?

i can't solve one pascal problem, first i have to enter N which is the number or mesurments, next i enter those mesurments (if N is 5 i enter 5 mesurments for exmaple 3 4 5 6 7). After that i enter Q which is the number of times i check the number of different numbers in a specific part of the row. For example you have input
5 (number of mesurments)
1 2 3 3 4 (mesurments)
3 (number of checkings)
1 3
3 4
1 5 (left number is the starting number from the row, if it's 1 you start from 1, if it's 4 you start from 3 because 3 is the fourth mesurment and the right number is the last number if it's 5 it would be 4 because 4 is the fifth in the row)
And for output you would get
3
1
4 (for the first checking you have number from 1 to 3 (1 2 3) and you have 3 different numbers, second mesurment from 3 to 4 (3 3) and it's 1 different number and last from 1 to 5 there are 4 different numbers)
Hope you understod me, and thanks if you can solve it, i am in highschool now and i am preparing my self for something more complicating :) thanks in advance
The inequality operator of Pascal is <>

Strange behaviour of MATLAB combnk function

I am trying to generate all combination of 2 elements in a given range of numbers. I am using 'combnk' function as follows.
combnk(1:4,2)
ans =
3 4
2 4
2 3
1 4
1 3
1 2
combnk(1:6,2)
ans =
1 2
1 3
1 4
1 5
1 6
2 3
2 4
2 5
2 6
3 4
3 5
3 6
4 5
4 6
5 6
The order of combinations returned appears to change. I need to know the order in advance for my program to work properly.
Is there any solution to make sure I get the combinations in a consistent order?
Also, why is MATLAB showing this strange behavior?
The only solution I can think of so far is to first check the 1st entry of the result matrix and flip it up side down using 'flipud' function.
Update: By a little bit of experimenting I noticed the reverse order occurs only when the length of the set of numbers is less than 6. This is why combnk(1:6,2) produce the 'correct' order. Where as combnk(1:5,2) produce the results backwards. This is still big problem.
You could try nchoosek instead of combnk. I don't have the matlab statistics toolbox (only octave), so I don't know if nchoosek has any significant disadvanvatages.
This will solve the ordering issue:
a=combnk(1:4,2);
[~,idx]=sortrows(a);
aNew=a(idx,:);
I don't know why MATLAB is showing this behavior.

how do I put the results from an iteration into an array in matlab

a=[1 2 3 4
5 6 7 8
8 7 6 5
4 3 2 1]
for i=(1:4)
b=(a(i,:));
c=sort(b,2)
end
Please, How can I obtain the results from this iteration in a single array(4x4) instead of getting the results of c=sort(b,2) separately for each loop.
You don't have to use a loop at all! You're trying to sort the columns in each row. This can be achieved by supplying an optional argument to sort.
c=sort(a,2);
c=
1 2 3 4
5 6 7 8
5 6 7 8
1 2 3 4
should give you what you need. The argument 2 tells sort to sort a by columns. If you wanted to sort it by rows, you'd use c=sort(a,1)