Selecting and deleting duplicated rows for particular columns SQL - mysql

I have an sql table that saves Locations,
ID Name X Y Z
-------------------------
1 Loc1 12 24 45
2 Loc2 12 24 60
3 Loc3 54 32 33
4 Loc4 54 32 64
5 Loc5 98 66 90
6 Loc6 98 66 77
7 Loc7 44 50 98
Some Location coordinates (x and y) are duplicated by mistake
I want to select and delete one of them.
ID Name X Y Z
-------------------------
1 Loc1 12 24 45
2 Loc3 54 32 33
3 Loc5 98 66 90
4 Loc7 44 50 98
Is this possible with sql query?

I think you can use the alter-table command and just drop the whole column.
ALTER TABLE table_name
DROP COLUMN column_name

with cte
as
(
select *,row_number() over (partition by x,y order by x) as rn
)
delete from cte where rn>1
As seen pointed out in comments,this deletes a random row (undeterministic),to make it deterministic order by name in your case

For MySQL you can use:
DELETE mytable
FROM mytable
JOIN (SELECT MIN(ID) AS ID, X, Y
FROM mytable
GROUP BY X, Y
) AS t ON mytable.X = t.X AND mytable.Y = t.Y AND mytable.ID > t.ID
Demo here

Its easy:
Add an INDEX over the 2 Columns with IGNORE:
ALTER IGNORE TABLE YOUR_TABLE
ADD KEY (X,Y);
Thats all

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.

MySQL find difference in rows with duplicate column values

Suppose I have a table TAPS
id sequence card_tap time
1 1 61 1
1 1 62 10
1 2 2 20
1 2 2 20
2 11 12 5
2 11 12 5
2 12 62 10
2 12 61 20
I want to find the rows where id and sequence are the same while thecard_tap and time is not.
It should return
id sequence card_tap time
1 1 61 1
1 1 62 10
2 12 62 10
2 12 61 20
This assume there is only two rows for each {id,sequence}
SELECT t1.*
FROM taps t1
JOIN taps t2
ON t1.id = t2.id
AND t1.sequence = t2.sequence
WHERE t1.time <> t2.time
OR t1.card_tap <> t2.card_tap
If you have more than two rows you will get duplicate rows so maybe need add DISTINCT
Simply with this ?
Select * from tabs where id = sequence and card_tap != time
The data seems to not be normalized. Anyway, based on your tagging, I'm guessing you're looking for something to return all results like:
select distinct * from taps;
or
select * from taps group by card_tap,time;
You need to add a unique ID with an Index to better deal with the data.

MySQL last 50 records

I have to get the last 50 records from my MySQL database.
Here is the structure of my test database:
ID S1 S2 S3 Date-time Label
13 32 55 33 2017-09-05 13:15:06 temperature
16 111 222 66 2017-09-05 19:22:14 temperature
17 44 55 33 2017-09-05 19:22:14 temperature
18 55 11 88 2017-09-12 14:22:00 temperature
21 77 1 200 2017-09-15 12:24:06 temperature
22 22 55 11 2017-09-19 14:37:00 temperature
How could I show only the last 3 data? for example:
18 55 11 88 2017-09-12 14:22:00 temperature
21 77 1 200 2017-09-15 12:24:06 temperature
22 22 55 11 2017-09-19 14:37:00 temperature
Greetings and thank you.
In Oracle12c you can use the fetch keywork:
SELECT *
FROM table
ORDER BY id DESC
FETCH FIRST 50 ROWS ONLY;
FOR ORACLE:
SELECT * FROM (
SELECT ID,
S1,
S2,
S3,
Date-time,
Label
FROM TABLE
ORDER BY ID DESC)
WHERE ROWNUM <= 50;
FOR MYSQL:
SELECT ID,
S1,
S2,
S3,
Date-time,
Label
FROM TABLE
ORDER BY ID DESC
LIMIT 50;
Here is a quick doc:
https://www.w3schools.com/sql/sql_top.asp
Edit:
For the last 50 rows:
SELECT * FROM (
SELECT * FROM table ORDER BY id DESC LIMIT 50
) sub
ORDER BY id ASC
Use Top N Query (row num<=50) fro first, for last 50 you can use "order by id desc"
First I was confused with the Post between ORACLE and MYSQL I apologize.
The solution at the end was the following:
SELECT * FROM inv ORDER BY id DESC LIMIT 50
then transform the ARRAY that I collect with the function:
var dorde = d0.reverse ();
thanks for everything.

MySQL calculate difference in count column between two queries

I have two different queries. One for "plus" and one for "minus". I want to find the difference in the count value for each player.
I tried union all and got some very weird numbers.
Here are the results of each query which I ned to find the difference of:
fk_plus_player1_id cnt
90 71
65 68
79 66
45 59
64 57
27 56
55 56
93 55
37 55
40 44
1 36
84 33
20 31
24 28
8 23
fk_minus_player1_id cnt
93 44
64 42
79 40
37 35
90 33
20 31
84 31
27 30
65 30
40 26
1 26
24 25
45 25
55 22
8 10
How would I accomplish this? Thanks in advance for your help. I am a noob...
UGH...Trying to do the join method. Having issues, getting no results, just 4 empty columns. This is what I am trying
SELECT
*
FROM
(
SELECT
statement for plus results here
) AS tp
JOIN (
SELECT
statement for minus results here
) AS tm ON tp.fk_plus_player1_id = tm.fk_minus_player1_id
GROUP BY
fk_plus_player1_id
suggestions??
You have two tables.
You want for each player, the difference of the counts.
So :
SELECT t1.fk_minus_player1_id AS player, ABS(t1.cnt - t2.cnt) AS difference
FROM table1 t1, table2 t2
WHERE t1.fk_minus_player1_id = t2.fk_plus_player1_id
GROUP BY t1.fk_minus_player1_id;
Maybe this is what you're looking for ?
WITH query1 AS
(SELECT t1.fk_minus_player1_id AS player, (t1.cnt - IFNULL(t2.cnt,0)) AS difference
FROM table1 t1 LEFT OUTER JOIN table2 t2 ON t1.fk_minus_player1_id = t2.fk_plus_player1_id
GROUP BY t1.fk_minus_player1_id),
query2 AS (SELECT t2.fk_plus_player1_id AS player, (IFNULL(t1.cnt,0) - t2.cnt) AS difference
FROM table2 t2 LEFT OUTER JOIN table1 t1 ON t1.fk_minus_player1_id = t2.fk_plus_player1_id
GROUP BY t2.fk_plus_player1_id)
(SELECT player, difference
FROM query1)
UNION
(SELECT player, difference
FROM query2 WHERE player NOT IN (SELECT player FROM query1))
You run the risk that the same players are not in both lists. The solution is union all with group by:
select player1id, sum(pluscnt) as pluscnt, sum(minuscnt) as minuscnt,
(sum(pluscnt) - sum(minuscnt)) as diff
from ((select player1id, cnt as pluscnt, 0 as minuscnt
from plustable
) union all
(select player1id, 0, cnt
from minustable
)
) t
group by player1id;

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 )