Delete duplicate rows with lowest values in another column in mysql - mysql

I'm newbie, and I'm trying to delete duplicate rows with highest value in another column,
This is My database and result of below query
SELECT file_id,src,dst,durations,date_time, COUNT(*), MAX(durations) as
Max_durations
FROM C2
WHERE durations in (
SELECT max(durations)
FROM C2
GROUP BY src, dst
HAVING COUNT(*) >1)
GROUP BY src,dst
HAVING COUNT(*)>1
Now I want to remove Duplicate rows but keep rows that have maximum duration or equal Max_duration column and if have same duration delete one of them.
How can i do it...?
src
dst
duration
COUNT
Max_duration
12014504264
9726341011
464
20
684
12014504264
9726645434
320
8
875
12014556435
9726876431
765
4
900
12014576565
9726347656
43
7
600
12014508754
9726344537
233
2
233
12014764532
9726877654
655
2
54
12014587875
9726645443
1345
5
982
12014654536
9726766433
73
2
84

Assuming you are trying to actually delete rows from the table, not just have a query that omits certain rows:
To do this, just self-join with a row that would be preferred to the current one, so only rows where that is found are deleted:
delete C2
from C2
join C2 preferred on
preferred.src=C2.src and
preferred.dst=C2.dst and
preferred.durations >= C2.durations and
(preferred.durations > C2.durations or preferred.file_id < C2.file_id)
But to do this, you need some unique column to establish a precedence between multiple rows with the maximum duration; here I am using file_id and keeping the row with the lowest file_id.

Related

correctly updating mysql column

i have this query and i am updating mysql column but when there are more than two rows for same shop_id it updates the same data for all rows and i can understand why.
tableA
ida shop_id balance
1 25 5000
2 30 8015
3 32 7550
ida is unique but shop_id and balance is not unique
tableB
id fquota used
25 5000 50
30 8015 80
32 7550 75
tableB id and tableA shop_id are same
as i am getting the balance value in first
SELECT tableA.shop_id,tableA.ida,tableB.fquota,tableB.used from tableA INNER JOIN tableB ON tableA.shop_id=tableB.id where tableA.delivered='1' order by tableA.ida asc limit 20
if this query returns this sort of data then same balance is updated
shop_id ida fquota used
50 151 5000 50
50 152 5000 50
50 153 5000 50
60 154 6000 100
so u can see that shop_id 50 is coming 3 times and everytime the fquota and used is same as we are doing in one query 20 rows so defenitely it will give wrong result for balance and update same value in this case
// $balanceeeddfkdkd = $fquota - $used - 20;
// $balanceeeddfkdkd = 5000-50-20
// same 4930 will be updated in ida 151,152,153
while($row2 = mysqli_fetch_assoc($re991))
{
$idaaaa=$row2['ida'];
$fquota =$row2['fquota'];
$used =$row2['used'];
$balanceeeddfkdkd = $fquota - $used - 20;
mysqli_query($con,"update tableA set balance='$balanceeeddfkdkd' where ida='$idaaaa' ");
}
everything works as expected problem happens when there are multiple rows for same customer.
in that case same balance is updated for multiple rows, any help will be great.
i want exact balance for each rows and as customer consumes balance will decrease but in our case if 5 rows are coming in that query for one customer, all 5 rows will be updated with same balance and reason is obvious as fquota and used values are taken once when we query to mysql
we tried with this DISTINCT but dont know why it did not work. it should have worked/
SELECT DISTINCT tableA.shop_id,tableA.ida,tableB.fquota,tableB.used from tableA INNER JOIN tableB ON tableA.shop_id=tableB.id where tableA.delivered='1' order by tableA.ida asc limit 20
Your problem does not reproduce.
I am trying to reproduce it here:
SQL FIDDLE
Insert data that will reproduce your issue.

How to reliably count preceding rows in MySQL?

I would like to know how to count preceding number of rows of a given row, in a given order by clause, in MySQL.
Also the rows may be inserted randomly, so auto_increment is unreliable.
MyAgenda - List
ID FROM TO
32 2017-09-26 12:35:00 2017-09-26 13:35:00
33 2017-10-10 12:35:00 2017-10-10 13:35:00
32 2017-10-17 12:35:00 2017-10-17 13:35:00
32 2017-10-24 12:35:00 2017-10-24 13:35:00
Like in this case, The rows are sorted by the "From" column, but apparently row 34 is inserted before row 36, but after sorting 36 is above 34, and if another row 37 is inserted it maybe above or below any row, or even at the top. So how can I reliably count the preceding number of rows above a given row, in a given order by clause?
Tried the subquery method but it is O(n^2) and will be painfully slow when the number of rows is large.
This counts records before record #36:
select count(*)
from mytable
where from_date < (select from_date from mytable where id = 36);
First I would suggest not to sort by one column only
try this
ORDER BY From, ID
about your question, not sure if i understood the question correctly but in that case this script may help
SELECT COUNT(*)
FROM your_table
WHERE From > #From
ORDER BY From, ID

MySQL substract rows under same column in same table but with varying primary key

I am new to this forum and to the MySQL. My question would be similar to the previous posts however would like to know if this can be solved with code.
I have table in mysql with primary key as id, Month (In date format) and Site Count.
Now I want a table output which contains Month, Site count and difference in between the count calculated from site count.
ID Month Site Count
1 31-01-2014 37
256 28-02-2014 37
512 31-03-2014 37
768 30-04-2014 41
1024 31-05-2014 38
1280 30-06-2014 42
1536 31-07-2014 42
Note: The reason ID is not in order is because it is derived from the main table.
Site count is derived value from the main table count(distinct site) as site count
Now I want the table to be created as below which can not be calculated using Id field
ID Month Site Count Diff
1 31-01-2014 37 0
256 28-02-2014 37 0
512 31-03-2014 37 4
768 30-04-2014 41 2
1024 31-05-2014 43 1
1280 30-06-2014 44 2
1536 31-07-2014 46
Last value could not be calculated as there is preceding value
Your help will be much appreciated.
Thanks.
You can do this with either variables or correlated subqueries/join. Here is the latter method:
select t.id, t.month, t.sitecount, (next_sitecount - sitecount) as diff
from (select t.*,
(select t2.sitecount
from t t2
where t2.month > t.month
order by month
limit 1
) as next_sitecount
from t
) t;

Oracle query issue in implementing logic for checking on million records

I have a table A
code_Value key_value Description
12 12 Entry_Category5
13 rrtt Entry2
20 tht Entry6
20 trt Wntry9
Table A has similar ways million records..
A logic is implemented in Table B which uses Table A as source
Code_value Key_value Description
12 12 Entry_Category5
13 rrtt Entry2
13 13 Null value
20 tht Entry6
20 trt Entry9
20 20 Null value
The logic is, in table A if i have an entry, where code is not equal to key then a new entry of my previous code will be copied with key as the code,description must be null.
This logic must be applied to million records.I just want to have an sql query which will
help me.Please suggest since there are more records
Try:
insert into table_b
select
code_value,key_value,description
from
table_a
where
code_value = key_value
union
select
code_value,code_value,null
from
table_a
where
code_value != key_value

MySQL SUM outputs wrong value in a query consisting multiple joins

I'm getting information on these tables using the following query, however defenderhit and defenderdamage SUM values are getting multiplied with the row count of first join's row number.
Table 'battles':
battle_id city_id attacker defender battle_time
1 07 6 0 1342918014
Table 'battlehits':
battle_id family_id user_id hits damage
1 0 0 1000 50000
1 6 15 108 3816
1 6 2 81 2046
1 6 1 852 1344
MySQL Query:
SELECT b.battle_id, b.city_id, b.attacker, b.defender, b.battle_time,
SUM(COALESCE(bh1.damage,0)) AS attackerdamage, SUM(COALESCE(bh2.damage,0)) AS defenderdamage,
SUM(COALESCE(bh1.hits,0)) AS attackerhit, SUM(COALESCE(bh2.hits,0)) AS defenderhit
FROM battles AS b
LEFT JOIN battlehits AS bh1 ON b.attacker = bh1.family_id
LEFT JOIN battlehits AS bh2 ON b.defender = bh2.family_id
WHERE b.battle_id=1
GROUP BY b.battle_id LIMIT 1
Result of this query is as following:
battle_id city_id attacker defender battle_time attackerdamage defenderdamage attackerhit defenderhit
1 07 6 0 1342918014 7206 150000 1041 3000
As you can see in the table data, defenderhit and defenderdamage SUM values are supposed to be 1000 and 50000, but they're multiplied by 3.
What am I doing in here? What's the problem?
Thanks in advance.
You are getting three rows, before the group by/sum. You have one row for each of the three attacker rows from battlehits. Each of these is paired with the same defender row from battlehits, causing the defender data to be tripled. To see this, remove the group by and limit clauses and take out the sum()s. You are effectively creating the cross product of all defenders X all attackers, and then summing.
This shows the three rows with duplicated defender data. This is a consequence of doing a join on a one to many to many relationship, instead of a one to one to one.
SELECT b.battle_id, b.city_id, b.attacker, b.defender, b.battle_time,
COALESCE(bh1.damage,0) AS attackerdamage, COALESCE(bh2.damage,0) AS defenderdamage,
COALESCE(bh1.hits,0) AS attackerhit, COALESCE(bh2.hits,0) AS defenderhit
FROM battles AS b
LEFT JOIN battlehits AS bh1 ON b.attacker = bh1.family_id
LEFT JOIN battlehits AS bh2 ON b.defender = bh2.family_id
WHERE b.battle_id=1;
Output:
battle_id city_id attacker defender battle_time attackerdamage defenderdamage attackerhit defenderhit
1 7 6 0 1342918014 3816 50000 108 1000
1 7 6 0 1342918014 2046 50000 81 1000
1 7 6 0 1342918014 1344 50000 852 1000
You need to split this into separate queries. One for the attacker sums and another for the defender sums.
You can emulate a SUM of distinct rows by using
(SUM(t.field_to_sum) / COUNT(t.primary_key) * COUNT(DISTINCT t.primary_key))