This question already has answers here:
How to delete duplicates on a MySQL table?
(25 answers)
Closed 3 years ago.
I have a SQL Tabel with three column id, Username, and Video I need a SQL query to remove all duplicates thanks
table SS link https://ibb.co/wC4p7kS
Since your screenshot is of phpMyAdmin, I'm going to assume that we're talking about MySQL here (when asking questions, that's helpful information as various SQL dialects have different tools that can be used).
If you don't need id in your results, you can just use DISTINCT:
SELECT
DISTINCT
Username,
Video
FROM
YourTableName
This returns a list of distinct rows (meaning it considers all columns in determining what is distinct, which is why including id here won't work).
If you do need to return an ID, you would have to use GROUP BY:
SELECT
MIN(id) AS id,
Username,
Video
FROM
YourTableName
GROUP BY
Username,
Video
Obviously from there, you could select a different ID (MAX(id) for example), or you could select a list of IDs using GROUP_CONCAT (e.g. GROUP_CONCAT(id ORDER BY id ASC) AS id, which will give you a comma-separated list by default unless you change it)
It can also be done using window/analytic functions, which can be a value in very large tables.
Note: When you say "remove all duplicates", I'm assuming you mean from your results. If you mean literally delete them from the table, you could use this:
DELETE FROM
YourTableName
WHERE
id NOT IN(SELECT MIN(id) FROM YourTableName GROUP BY Username,Video)
Related
I am making a small php website in which you can follow others and then see their post.
I have three tables-
1.Posts, which has post_id and author_id
2.follow, which has following and follower
3.users, which has id, username, and all other stuff. I try the following in sql-
SELECT * FROM posts,follow,users WHERE posts.author_id=users.id AND users.id=follow.following AND follow.follower='$id' UNION SELECT * FROM posts,users WHERE posts.author_id=users.id AND users.id='$id'
Where $id is the id of the user logged in.
It displays the following error-
#1222 - The used SELECT statements have a different number of columns
I have searched for hours but I cannot find the answers to match with my query.
I will really appreciate an answer with a better version of the above code.
Thanks in advance.
Perhaps a JOIN would serve you better ... something like this:
SELECT * FROM posts
JOIN users on posts.author_id=users.id
JOIN followers on users.id=follow.following
WHERE follow.follower='$id'
When you union two queries together, the columns on both must match.
You select from posts,follow,users on the first query and posts,users on the second.
this won't work.
From the mysql manual:
The column names from the first SELECT statement are used as the column names for the results returned. Selected columns listed in corresponding positions of each SELECT statement should have the same data type
I'm a bit confused about DISTINCT keyword. Let's guess that this query will get all the records distincting the columns set in the query:
$query = "SELECT DISTINCT name FROM people";
Now, that query is fetching all the records distincting column "name" and at the same time only fetching "name" column. How I'm supposed to ONLY distinct one column and at the same time get all the desired columns?
This would be the scheme:
NEEDED COLUMNS
name
surname
age
DISTINCTING COLUMNS
name
What would be the correct sintaxis for that query? Thanks in advance.
If you want one row per name, then a normal method is an aggregation query:
select name, max(surname) as surname, max(age) as age
from t
group by name;
MySQL supports an extension of the group by, which allows you to write a query such as:
select t.*
from t
group by name;
I strongly recommend that you do not use this. It is non-standard and the values come from indeterminate matching rows. There is not even a guarantee that they come from the same row (although they typically do in practice).
Often, you want something like that biggest age. If so, you handle this differently:
select t.*
from t
where t.age = (select max(t2.age) from t t2 where t2.name = t.name);
Note: This doesn't use group by. And, it will return duplicates if there are multiple rows with the same age.
Another method uses variables -- another MySQL-specific feature. But, if you are still learning about select, you should probably wait to learn about variables.
This question already has answers here:
Delete duplicated records from a table without pk or id or unique columns in mysql
(4 answers)
Closed 7 years ago.
EDIT: I added a response with the link and command that solved my issue. To put it straight for any future readers desperate about their unindexed tables with duplicate rows, you'll find the answer bellow or in the link above.
I have a little screwed up table in my db. It was repeated row with the exact same information (including id).
Is there a query I can use to delete these repeated id's but one?
I wanted to check my answer here first, if I delete this table it's going to take me the whole weekend to import it again (it's huge)...
I'm thinking of doing
DELETE FROM tickets t1, tickets t2 WHERE t1.id = t2.id limit 1;
I'm not sure this will work...
Thanks!
As Oceans says
CREATE TEMPORARY TABLE tmp_tickets AS SELECT DISTINCT * FROM tickets;
DELETE FROM tickets;
INSERT INTO tickets SELECT * FROM tmp_tickets;
DROP TABLE tmp_tickets;
To find all the duplicates in the id column you could try:
select `id`
from `tickets`
group by `id`
having count(`id`)>1;
I would try this in a gui ( Heidi etc ) ~ you can then base your delete operations around this, either manually in the gui or by direct query.
I managed to fix this with the solution found here Remove duplicate rows in MySQL. To save you clicking the link the query looked something like this
ALTER IGNORE TABLE jobs
ADD UNIQUE INDEX idx_name (site_id, title, company);
It removed all the repeated indexes, minus one.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
How to request a random row in SQL?
I have table:
name,age,school
jane,15,zu
peter,16,zu
john,15,stu
Tomas,15,kul
viera,17,stu
tibor15,zu
I want select from this table 1 person (randomly) per school
select * from table group by school order by rand()
It's terribly innefficient since it's ORDERing the entire table randomly, and then GROUPing on a potentially huge unindexed temporary table, but this works.
SELECT *
FROM (
SELECT *
FROM my_table
ORDER BY RAND()
)a
GROUP BY school
It would likely be more wise to break it down.
One query to retrieve a list of
schools.
For each school, one query to get a random student for that school.
See this post for some slick tricks on how to get single random values efficiently.
If you are using php (as the tag suggests), run SELECT * FROM table; then generate a random number based on the number of results in the query. For example:
i = floor(random()*query.length);
Then seek to the record indicated seek(i) and viola, you have a random entry =)
You'll have to use your own knowledge/documentation for the exact syntax, I haven't touched PHP in a while, but the logic is sound.
Gary
With PHP I'm trying to run a SQL query and select normal columns as well as COUNT.
$sql_str = "select COUNT(DISTINCT name), id, adress from users";
$src = mysql_query($sql_str);
while( $dsatz = mysql_fetch_assoc($src) ){
echo $dsatz['name'] . "<br>";
}
The problem is that when I have "COUNT(DISTINCT name)," in my query, it will only return the first entry. When I remove it, it will return all matching entries from the db.
I could separate it and do 2 queries, but I'm trying to avoid this due to performance concerns.
What do I make wrong?
thx, Mexx
The ability to mix normal columns and aggregate functions is a (mis)feature of MySQL.
You can even read why it's so dangerous on MySQL's documentation:
https://dev.mysql.com/doc/refman/5.6/en/group-by-extensions.html
But if you really want to mix normal rows and a summary in a single query, you can always use the UNION statement:
SELECT COUNT(DISTINCT name), null, null FROM users GROUP BY name --summary row
UNION
SELECT name, id, address FROM users --normal rows
COUNT() is an aggregate function, it aggregates against the results of the rest of your query. If you want to count all distinct names, and not just the distinct names associated with the id and address that you are selecting, then yes, you will have to run two queries. That's just how SQL works.
Note that you should also have a group by clause when aggregating. I think the fact that MySQL doesn't require it is horrible, and it encourages really bad habits.
From what I understand, you want to get :
one line per user, to get each name/id/address
one line for several users at the same time, to get the number of users who have the same name.
This is not quite possible, I'd say.
A solution would be, like you said, two queries...
... Or, in your case, you could do the count on the PHP side, I suppose.
ie, not count in the query, but use an additionnal loop in your PHP code.
When you have a count() as part of the field list you should group the rest of the fields. In your case that would be
select count(distinct name), id, adress from users group by id, adress
select count(distinct name), id, adress
from users
group by id, adress
I'm assuming you want to get all your users and the total count in the same query.
Try
select name, id, address, count(id) as total_number
from users
group by name, id, address;