Selectively delete mostly duplicate records from MySQL - php

I have a table:
PRICE_UPDATE
id (int 5, auto-increment, primary, unique)
part_number (varchar 10, non-null)
price (float(10,2), non-null)
Some of the part_numbers are duplicated (1 or more duplicate records). Sometimes with the same price, sometimes with different prices.
How can I delete all of the duplicate rows based on part_number, leaving either the highest price or just 1 record if the prices were all the same?
Is this even doable in straight MySQL?

DELETE t1
FROM YourTable t1, YourTable t2
WHERE t1.part_number = t2.part_number
AND (t1.price, t1.id) < (t2.price, t2.id)

From inside, to outside:
Selects the ids with the max price per part_number
Selects the max id with the max price per part_number
Deletes the ids not present in 2.
delete tablename where id not in (
(select max(id) from tablename a
inner join
( select id, max(price)
from tablename
group by part_number ) b on a.id = b.id and a.price = b.price
group by part_number))

Related

SQL Join with subquery counting number of records with the same id in a different table

Okay so I have three(3) tables that i want to join together
tableA is the main details and primary key is row_id autoincremented
tableB is the exteded details and primary/foreign key is row_id coming from tableA
tableC stores unordered ratings and comments for a particular row_id
I want to join all these tables so that I can see all details plus the number of instances in tableC for a row_id and the avg rating.
SELECT *
FROM `tableA` A
LEFT JOIN `tableB` B
ON A.`row_id` = B.`row_id`
LEFT JOIN (
SELECT COUNT( 1 ) AS 'count', Avg(`row_rating`) AS 'avg'
FROM `tableC`
GROUP BY tableC.`row_id`
)C
ON C.`row_id` = A.`row_id`
ORDER BY C.`avg` ASC
The result of this query combines all properly but the same count and avg is displayed in all rows.
Looks like you want to group the records by row_id in inner query. In which case, you need to SELECT row_id instead of COUNT(1), try this:
SELECT *
FROM `tableA` A
LEFT JOIN `tableB` B
ON A.`row_id` = B.`row_id`
LEFT JOIN (
SELECT row_id, Avg(`row_rating`) AS 'avg'
FROM `tableC`
GROUP BY tableC.`row_id`
)C
ON C.`row_id` = A.`row_id`
ORDER BY C.`avg` ASC

Ordering rows by count in a separate pivot table

I have a main table: Images and votes.
The votes contains 2 fields: Id, image_id
What I wish to do is query the images table and return them ordered by the amount of votes in the vote table.
Currently:
$stmt = $conn->prepare(
'SELECT *
FROM images
LIMIT 10'
);
I understand basic left joins, but cannot think how to order them by count of votes. Just need a starting example.
Thanks
Assuming that each row in your VOTES table means one vote towards the image, this should work: SQL DEMO
SELECT *, COUNT(v.image_id)
FROM images AS i
LEFT JOIN votes AS v ON i.id=v.image_id
GROUP BY i.id
ORDER BY v.image_id desc
drop table if exists t1;
create table t1 (id int);
insert into t1 values (1), (2), (3);
drop table if exists t2;
create table t2 (id int, img_id int);
insert into t2 values (1, 1), (2, 1), (3, 2), (4,1), (5,3), (6,2);
select *
from t1
left join
(select img_id, count(*) count
from t2
group by img_id) c
on img_id=t1.id
order by count
Demo on sqlfiddle

Selecting specific rows from table

I have the below table (in picture) which is kind of inventory table and shows how many items comes in and how many goes out from stock, and item_id is the foreign key from another table.
I want to select those records that has no out from the stock, in other word i want to select those records which are highlighted in green (in the picture).
Thanks.
Sorry for poor English
The Table
Try this:
Select * from `table` where id in (select id from `table`group by id having sum(out)=0);
for deleting those values use:
delete t1
from `your_table` as t1
join (select item_id from `your_table`group by item_id having sum(item_out)=0) t2 on t1.item_id = t2.item_id
Try this query.
SELECT * FROM 'table_name' where out=0;
You need to join the table to itself: SELECT t.* FROM <your_table> AS t LEFT JOIN <your_table> AS t1 ON t.item_id=t1.item_id WHERE t1.out>0 AND t1.item_id IS NULL

Need the highest ID using left join

I have two tables,
TABLE 1 has many of each client and campaign and is very large
TABLE 2 has only one of each client and campaign and is small.
So I want to get the lastest(highest ID) from TABLE 1 where it matches the client and campaign in TABLE 2 and only one of each.
I have tried MAX, and playing with the order by etc, but cant get it working....
The results I get are choosing the lowest ID from TABLE 1 (I want highest)
$result2 = mysql_query("SELECT table1.client,table1.campaign,table1.id
FROM table1
LEFT OUTER JOIN
table2
ON (table2.client = table1.client)
AND (table2.campaign = table1.campaign )
WHERE (table2.enabled != 'disabled')
group by campaign asc
order by client,campaign,id asc
");
Help needed....
SELECT * FROM table1
INNER JOIN
(
SELECT MAX(table1.id) AS id FROM table1
INNER JOIN table2 ON table2.client = table1.client AND table2.campaign=table1.campaign and table2.enabled != 'disabled'
GROUP BY table1.client, table1.campaign
) AS m ON m.id = table1.id
I think that's what you're asking for. For each combination of client and campaign that exists in each table, it will give you the highest ID in table 1.

PHP / MYSQL Statement so select Max Sum of Join

I have Problems with a select statement, as a little help here are the important columns:
Table1
ID NAME
TABLE 2
ID U_ID COUNTER
The ID of Table 1 Matches the U_ID of Table 2. Table 2 contains many entries for the same u_id.
What I want to do is to get the Name of the "user" (table 1) who has in sum the max. counter.
What I got since now is the join of the tables (Where clause depends on other rows which are not important for the problem).
Can anyone help me on this issue?
So what you need is an aggregate of an aggregate (max of sum of column). The easiest will be to create a view providing the sum and u_id end then select the max of it:
create view table2sums
as
select u_id, sum(counter) as total
from table2
group by u_id;
and then
select t1.name
from table1 t1, table2sums t2
where t1.id = t2.u_id
and t2.total >= all (
select total
from table2sums
)
In this special case you can also do it directly:
select t1.name
from table1 t1, table2 t2
where t1.id = t2.u_id
group by t1.name
having sum(t2.counter) >= all (
select sum(counter)
from table2
group by t2.u_id
)
NOTE: The other proposed solutions will show a better performance. My solution only selects the name (which is what you said you wanted) and works in any RDBMS.
There exist RDBMS without the LIMIT possibility.
In the end, I'd say: regard my solution as educational, the others as practical
SELECT name,
SUM(counter) as counter
FROM table1
JOIN table2
ON table1.id = table2.u_id
GROUP BY u_id
ORDER BY counter DESC
LIMIT 1
You can try this:
SELECT name, SUM(counter) as total_counter
FROM table1
JOIN table2
ON table1.id = table2.u_id
GROUP BY u_id
ORDER BY total_counter DESC
LIMIT 1
Working Demo: http://sqlfiddle.com/#!2/45419/4

Categories