Create result sets from matches across 2 tables - sql-server

Given a set of results in table 1
Col 1 Col 2 Col 3 Result
A B C 1
A B D 2
A B D 3
A B E 4
A B E 5
A B F 6
and a set of conditions in table 2
Col 1 Col 2 Col 3
A B C
A B D
A B E
how do I return a table of 'Result Sets' (or grouped results) in T-SQL to identify all the possible combinations of results from table 1 where all conditions in table 2 are met?
Result Set Result
1 1
1 2
1 4
2 1
2 2
2 5
3 1
3 3
3 4
4 1
4 3
4 5
EDIT: To clarify, the 'Result Set' value in the output table would be generated in the T-SQL to identify each set of results.

Related

SQLite: combination of different ordering policies in one query

I have a table which holds 4 columns: int x, int y, int z, int type.
I need to select sorted list of records when next properties preserved:
All records with type 1 must be ordered by x and y (y is secondary key) in ascending order;
All records of type 2 must be ordered by z. In ascending order.
Records of type 2 usually ordered by x and y and when ordered by z the ordering should be the same. In theory. However, in reality some of type 2 records may be partially disordered with respect to z, i.e. for them table.x2 > table.x1 but table.z2 < table.z1.
I need for all selected records of type 2 to ensure table.z2 > table.z1 even at price of having table.x1 > table.x2 (implied, that table.x1 < table.x2 for all other records).
I figured out some query like this:
SELECT * FROM aTable ORDER BY CASE type WHEN 1 THEN x ASC, y ASC ELSE z ASC END;
but for some reason SQLite rejects it as syntactically wrong.
Is it possible anyway to construct such query?
UPDATE:
Example
Data in table
x y z type
1 4 3 1
2 3 6 1
2 2 6 1
8 3 5 2
4 6 3 2
5 8 6 1
7 6 2 2
Expected result:
1 4 3 1
2 2 6 1
2 3 6 1
7 6 2 2
4 6 3 2
5 8 6 1
8 3 5 2

how work with groups of a data set with respect of a column?

how I can fin the first and last elements of a dataframe based on a group of rows with respect of a column?
df1:=
g col1 col2
h 1 2
h 0 1
h 7 8
h 5 2
h 0 1
k 7 3
k 2 1
k 9 1
if I wanna group the column with respect of g, and for each group and column I need the following information:
first element, last element, size of the group
IIUC, try:
df_g = df.groupby('dates1').agg(['first','last','size']).T.unstack()
df_g.columns = [f'{i}/{j}' for i, j in df_g.columns]
print(df_g)
Output:
2020-01/first 2020-01/last 2020-01/size 2020-02/first 2020-02/last 2020-02/size
col1 7 9 3 1 0 5
col2 3 1 3 2 1 5

Enforce same value for the combination of two other values

I have a table T, where I have 4 (integer) columns, A, B, C, and D. There is already a UNIQUE constraint on ABC, but I would need to write a constraint enforcing, that for the same AB combination, the D has the same value, no matter what C is. I.e.
A B C D Note
1 1 1 1 AB is 1,1, D is 1
1 1 2 1
1 1 3 2 wrong! D must be 1, because AB is 1,1
1 1 4 1 ok
2 1 1 5 ok, it's a new AB combination, so a new D value is possible
2 1 2 5 D must be 5 here (and for any following row with AB 2,1)
etc.
I have no idea where to start, and my Google-fu is weak in this case.

How to remove reverse rows in a permutation matrix?

I'm looking for a quick way in MATLAB to do the following:
Given a permutation matrix of a vector, say [1, 2, 3], I would like to remove all duplicate reverse rows.
So the matrix P = perms([1, 2, 3])
3 2 1
3 1 2
2 3 1
2 1 3
1 3 2
1 2 3
becomes
3 2 1
3 1 2
2 3 1
You can noticed that, symetrically, the first element of each rows have to be bigger than the last one:
n = 4; %row size
x = perms(1:n) %all perms
p = x(x(:,1)>x(:,n),:) %non symetrical perms
Or you can noticed that the number of rows contained by the p matrix follows this OEIS sequence for each n and correspond to size(x,1)/2 so since perms output the permutation in reverse lexicographic order:
n = 4; %row size
x = perms(1:n) %all perms
p = x(1:size(x,1)/2,:) %non symetrical perms
You can use MATLAB's fliplr method to flip your array left to right, and then use ismember to find rows of P in the flipped version. At last, iterate all locations and select already found rows.
Here's some code (tested with Octave 5.2.0 and MATLAB Online):
a = [1, 2, 3];
P = perms(a)
% Where can row x be found in the left right flipped version of row x?
[~, Locb] = ismember(P, fliplr(P), 'rows');
% Set up logical vector to store indices to take from P.
n = length(Locb);
idx = true(n, 1);
% Iterate all locations and set already found row to false.
for I = 1:n
if (idx(I))
idx(Locb(I)) = false;
end
end
% Generate result matrix.
P_star = P(idx, :)
Your example:
P =
3 2 1
3 1 2
2 3 1
2 1 3
1 3 2
1 2 3
P_star =
3 2 1
3 1 2
2 3 1
Added 4 to the example:
P =
4 3 2 1
4 3 1 2
4 2 3 1
4 2 1 3
4 1 3 2
4 1 2 3
3 4 2 1
3 4 1 2
3 2 4 1
3 2 1 4
3 1 4 2
3 1 2 4
2 4 3 1
2 4 1 3
2 3 4 1
2 3 1 4
2 1 4 3
2 1 3 4
1 4 3 2
1 4 2 3
1 3 4 2
1 3 2 4
1 2 4 3
1 2 3 4
P_star =
4 3 2 1
4 3 1 2
4 2 3 1
4 2 1 3
4 1 3 2
4 1 2 3
3 4 2 1
3 4 1 2
3 2 4 1
3 1 4 2
2 4 3 1
2 3 4 1
As demanded in your question (at least from my understanding), rows are taken from top to bottom.
Here's another approach:
result = P(all(~triu(~pdist2(P,P(:,end:-1:1)))),:);
pdist computes the distance between rows of P and rows of P(:,end:-1:1).
~ negates the result, so that true corresponds to coincident pairs.
triu keeps only the upper triangular part of the matrix, so that only one of the two rows of the coincident pair will be removed.
~ negates back, so that true corresponds to non-coincident pairs.
all gives a row vector with true for rows that should be kept (because they do not coincide with any previous row).
This is used as a logical index to select rows of P.

Eliminate repeated vectors but with elements on different order

I have a matrix A which is (243 x 5). I want to pick the unique row vectors of that matrix but taking into account that row vectors with the same elements but in different order shall be considered as being the same.
E.g., suppose for simplicity that the A matrix is (10 x 5) and equal to:
A=[1 2 1 2 3
1 3 1 1 1
1 3 1 1 2
1 2 1 1 3
2 3 1 2 1
1 3 1 2 2
1 3 1 2 3
1 3 1 3 2
1 3 1 3 1
1 3 2 3 1]
On the example above, rows (1, 5, 6) are to be considered equivalent they have the same elements but in different order. Also, rows (3 and 4) are equivalent, and rows (7, 8, 10) are also equivalent.
Is there any way to write a code that removes all "repeated rows", i.e. a code that delivers only the rows (1, 2, 3, 7 and 9) from A?
So far I came across with this solution:
B(:,1) = sum(A == 1,2);
B(:,2) = sum(A == 2,2);
B(:,3) = sum(A == 3,2);
[C, ia, ic] = unique(B,'rows');
Result = A(ia,:);
This delivers what I am looking for with one caveat - it is delivering the unique rows of A according to the criteria defined above, but it is not delivering the first row it finds. I.e. instead of delivering rows (1,2,3,7,9) it is delivering rows(7, 1, 9, 3, 2).
Anyway I can force him to deliver the rows in correct order? Also any better way of doing this?
You can do it as follows:
Sort A along the second dimension;
Get stable indices of unique (sorted) rows;
Use the result as row indices into the original A.
That is:
As = sort(A, 2);
[~, ind] = unique(As, 'rows', 'stable');
result = A(ind,:);
For
A = [1 2 1 2 3
1 3 1 1 1
1 3 1 1 2
1 2 1 1 3
2 3 1 2 1
1 3 1 2 2
1 3 1 2 3
1 3 1 3 2
1 3 1 3 1
1 3 2 3 1];
this gives
result =
1 2 1 2 3
1 3 1 1 1
1 3 1 1 2
1 3 1 2 3
1 3 1 3 1

Resources