How to get permutation of a table? - mysql

I have one table with 10 columns. I want to get all the possible permutations. example for table with 3 columns:
col1 col2 col3
10 40 3,
20 6 1,
the permutation table will be:
col1 col2 col3
10 40 3,
10 40 1,
10 6 3,
10 6 1,
20 6 1,
20 6 3,
20 40 3,
20 40 1,
I've tried to do it with CROSS JOIN, but didn't success.
what is the best way to do it?
Thank you!

You can use a cross join:
select c1.col1, c2.col2, c3.col3
from (select distinct col1 from t) c1 cross join
(select distinct col2 from t) c2 cross join
(select distinct col3 from t) c3
order by c1.col1, c2.col2, c3.col3;
Here is a db<>fiddle.

Related

how to detect peak of two columns in sql

I have two columns in mysql:
row A B
1 90 80
2 80 57
3 57 5
4 48 30
5 30 15
I need to compare the value of B and the next value of A, how could I detect a peak when B is 5 (row 3) and A is 48 (row 4)? New column can be added to say whether a peak is detected.
The result should be:
row A B peak_detection
1 90 80 0
2 80 57 0
3 57 5 0
4 48 30 1
5 30 15 0
Thank you
In steps:
How big is the difference:
SELECT
A,
B,
LAG(A) over (order by r)-B difference
FROM Table1
Select the max row:
SELECT r
FROM (
SELECT
r,
A,
B,
LAG(A) over (order by r)-B difference
FROM Table1
) t2
ORDER BY difference DESC
LIMIT 1
Add the column peak_detection:
SELECT
A,
B,
IF(Table1.r=t2.r,1,0) peak_detection
FROM Table1
LEFT JOIN (
SELECT r
FROM (
SELECT
r,
A,
B,
LAG(A) over (order by r)-B difference
FROM Table1
) t2
ORDER BY difference DESC
LIMIT 1
) t2 on t2.r=Table1.r
See: dbfiddle
output:
A
B
peak_detection
90
80
0
80
57
0
57
5
1
48
30
0
30
15
0
P.S. code improvement can be done (and might be needed) on the last query, if needed.

select rows related with a column

I have table like this;
col1 col2 col3 week
a b c 21
a f g 22
c d e 23
a e f 24
f g h 25
a c f 26
f b e 27
I want to count rows those including 'a' with 1 week difference and 2 weeks and so on.For example;
2 times with 1 week difference, 1 times with 0 difference.Like;
week diff. count
0 1
1 2
2 0
an so on.
Thanks and i tried to be clear with my poor English.
I'm not sure I understand the problem. But, supposing that:
You want to count rows with 'a' in any column (col1, col2, col3).
When you say "2 times with 1 week difference", it's 2 times because 'a' appears in 2 consecutive weeks: 21 and 22.
Same way, there would be 3 rows (so, 3 times) with "2 week difference": rows with week column equal to 22, 24, 26
Then, the following query could be helpful:
SELECT
ABS(t2.week - t1.week) AS week_difference,
COUNT(DISTINCT t1.week) AS count
FROM
temp t1, temp t2
WHERE
((t1.col1 = 'a' OR t1.col2 = 'a' OR t1.col3 = 'a')
AND (t2.col1 = 'a' OR t2.col2 = 'a' OR t2.col3 = 'a'))
AND ABS(t2.week - t1.week) <= 2
GROUP BY
week_difference
ORDER BY
week_difference

Group by adjacent rows based on two columns

Let's say I have a table like this:
id col1 col2
---------------------
1 35 A
2 40 B
3 39 B
4 39 B
5 39 B
6 40 B
7 39 B
8 39 B
9 40 B
10 40 C
11 35 C
How do I make it so that it has a result like this:
id col1 col2
---------------------
1 35 A
2 40 B
3 39 B
6 40 B
7 39 B
9 40 B
10 40 C
11 35 C
I want to group by col1 that has same value in adjacent rows while also has same group in col2 (col1 values in id:9 and id:10 couldn't be grouped because it has different col2 value)
Any help would be appreciated, thanks!
The key idea is to get a grouping identifier for the adjacent rows. The question is: what characteristic of the rows is constant for rows that should be grouped together?
Well, here is one: the number of previous rows (based on id) that have different values in either col1 or col2 is the same for all rows in a group.
You can turn this observation into a measure for each row (using a correlated subquery). The rest is just aggregation:
select min(id) as id, col1, col2, count(*) as NumInGroup
from (select t.*,
(select count(*)
from t t2
where t2.id < t.id and (t2.col1 <> t.col1 or t2.col2 <> t.col2)
) as grp
from t
) t
group by grp, col1, col2;
demo: db-fiddle
Note: This will work well-enough on small amounts of data, but it does not scale particularly well.

Mysql Query Min And Max with Limit N Grouping

I'd like to ask some question about query.
This is my case:
Structure Table
codenumber varchar (PK)
prize varchar
batchno double
category varchar
Sample Data On Database:
Code Prize BatchNumber Category
1000000231 TRY AGAIN 1 A
1000000238 TRY AGAIN 2 A
1000000376 TRY AGAIN 3 A
1000000473 TRY AGAIN 4 A
1000000934 50 5 A
1000001281 50 6 B
1000001894 50 7 B
1000002014 TRY AGAIN 8 B
1000002831 TRY AGAIN 9 B
1000003123 TRY AGAIN 10 B
1000003158 TRY AGAIN 11 C
1000003224 TRY AGAIN 12 C
1000003524 TRY AGAIN 13 C
1000003598 50 14 C
1000003616 TRY AGAIN 15 C
1000003657 TRY AGAIN 16 A
1000003959 50 17 A
1000004289 TRY AGAIN 18 A
1000004529 TRY AGAIN 19 A
1000004853 TRY AGAIN 20 A
1000005683 TRY AGAIN 21 B
1000005728 100 22 B
1000005816 TRY AGAIN 23 B
1000006325 TRY AGAIN 24 B
I wanted to get the Minimum and Maximum batch number for each 5 rows.
Then how to get the query result like below:
Category MinBatch MaxBatch
A 1 5
B 6 10
C 11 15
A 16 20
B 21 24
Please Help Thanks
Presuming that batch represents the ordering for determining groups of 5, you can do this with variables:
select category, min(batch), max(batch)
from (select s.*, (#rn := #rn + 1) as rn
from structure s cross join
(select #rn := 0) params
order by batch
) s
group by floor((rn - 1) / 5)
order by min(batch);
Actually, if you know the batches are consecutive with no gaps and start at 1:
select category, min(batch), max(batch)
from structure s
group by floor((batch - 1) / 5)
order by min(batch);
Below query will give you the result
select category, min(batchnumber)as 'MinBatch', max(batchnumber)as 'MaxBatch'
from tablename order group by (category)

how can you eliminate permutations between columns in MySQL

i have table columns one (idprocess) point to columns two (idporcess1) and point to columns tree (idprocess2).
id idprocess idporcess1 idprocess2
1 15 16 17 <== A
2 15 16 19 <== B
3 15 20 23
4 14 16 17
6 16 15 80 <== C
7 17 15 49 <== D
8 23 16 20 <== E
I need a SQL query that returns this: row c and row D, so with number idprocess(16) and idprocess(17 )
because row c : idprocess(16) references again ipdprocess1(15)
because row c : idprocess(17 ) references agin ipdprocess1(15)
please help
i want only to eleminate circular referencial in tree
If you are happy to find rows where the first two columns are permutated, this will do the job:
SELECT *
FROM my_tbl t
WHERE EXISTS (SELECT 1 FROM my_tbl t1 WHERE t1.idprocess = t.idprocess1 AND t1.idprocess1 = t.idprocess)
ORDER BY t.id;
Alternative interpretation:
If you want all rows where idprocess1 has been listed in idprocess before (before = smaller id), then you can:
SELECT *
FROM my_tbl t
WHERE EXISTS (SELECT 1 FROM my_tbl t1 WHERE t1.id < t.id AND t1.idprocess = t.idprocess1)
ORDER BY t.id;
You wouldn't call that "permutation", though.
The question is a bit ambiguous but I tried to understand it on my own and prepared the following query:
SELECT *
FROM TEMP
where C2 IN ( Select C2 FROM TEMP group by C2 having count(C2) > 1 )
OR C3 IN ( Select C3 FROM TEMP group by C3 having count(C3) > 1 )