Eliminate duplicate rows in mysql select statement - php

So hoping someone can help me on this. I've read so many questions on the same issue but none answer my question. I have the following SQL SELECT statement in my PHP code:
$sql = "
SELECT DISTINCT
pics.piclocation,
pics.picid,
rating
FROM
pics,
ratings
WHERE
pics.milfid = ratings.picid
ORDER BY
ratings.rating DESC
";
However as many know the DISTINCT keyword does not eliminate duplicate rows all the time. The problem is that the same picture is getting output often more than once i.e. pics.piclocation. The idea is each pic is rated from 1 to 5 which is then inserted into the ratings table.
Any ideas on how I can produce an output and eliminate duplication piclocation rows? I want the pictures to be listed based on which picture has the most 5 ratings if that helps any.
Thanks!

So if you only want images that have a rating of 5 then go ahead and select on that, then you can count the number of 5's that image has gotten and order by that. You will also then need to group by the unique identifer for an image which looks like its pics.milfid and ratings.picid.
SELECT
pics.piclocation,
pics.picid,
COUNT(ratings.rating) as nb_ratings
FROM
pics,
ratings
WHERE
pics.milfid = ratings.picid
AND ratings.rating = 5
GROUP BY
ratings.picid
ORDER BY
nb_ratings DESC
If instead you just wanted the highest rated pic, then you could SUM the ratings:
SELECT
pics.piclocation,
pics.picid,
SUM(rating) as total_rating
FROM
pics,
ratings
WHERE
pics.milfid = ratings.picid
GROUP BY
ratings.picid
ORDER BY
total_rating DESC

Related

DISTINCT and RND() on joined tables

I’m really struggling with how to write a query which randomly selects 50 DISTINCT random titles from one table in my MySQL database and then selects 1 random excerpt from each title from a separate table. The first table is titles and the second is excerpts.
I’ve tried two queries nested together but this either doesn’t work or returns duplicate titles despite supposedly being DISTINCT.
Could somebody please, PLEASE help me with where I’m going wrong?!
My existing PHP:
$distincttitlequery = “SELECT DISTINCT titleid FROM titles ORDER BY rand() LIMIT 50”;
$distincttitleresult = mysql_query($cxn,$distincttitlequery);
while ($distinctqueryreturn = mysqli_fetch_assoc($distincttitlequery))
{
extract ($distinctqueryreturn);
$selectedtitle = $titleid;
$randomexcerptquery = “SELECT excerpts.titleid, excerpts.excerptid, excerpts.excerptsynopsis, title.titleid, title.title FROM excerpts INNER JOIN titles ON excerpts.titleid=title.titleid WHERE titleid = ‘$selectedtitle’ ORDER BY rand() LIMIT 1”;
$randomexcerptresults = mysql_query($cxn,$randomexcerptquery);
while ($randomexcerptreturn = mysqli_fetch_assoc($randomexcerptquery))
{
[ECHO RESULTS HERE]
}};
I’ve read in similar posts about GROUP BY but I need to create a query which deals with distinct, random and joined tables and I have absolutely no idea where to start!
My existing code uses DISTINCT on multiple columns and joins the tables but this leads to titles being repeated in returned results. I can LIVE with that but I’d love to perfect it!
Thank you in advance for your help with this.
In mysql 8 you can use row_number to get 1 random row per titleid
SELECT
titleid,title,excerptid,excerptsynopsis
FROM (
SELECT
e.titleid, e.excerptid, e.excerptsynopsis
,ROW_NUMBER() OVER( PARTITION BY e.titleid ORDER BY rand()) rn
, t.title
FROM excerpts e
INNER JOIN (SELECT DISTINCT titleid FROM titles ORDER BY rand() LIMIT 50) t ON e.titleid=t.titleid
) t1
WHERE rn = 1

PHP MariaDB PDO count duplicate values

Maybe a stupid question, but I can't find anything on it. I know you can do counts and some basic math with queries.
Is there a way to make the database count and return results with the highest or lowest number of occurrences?
Lets say you had all the pages of a library in a database and you wanted to know the top 5 characters used or maybe the least used.
I guess the easiest example would be the lottery. Lets say you had a table of past lottery results. Lets say you wanted to return a list of the top 10 most drawn numbers. Lets say the numbers can range from 1 to 100.
It wouldn't be very efficient to run the following query 100 different times and then run some php to sort the data.
SELECT COUNT(*) FROM mytable WHERE ball=1
Surely there must be a way to return a count of the most duplicated data.
Perhaps I am over thinking this. Anyway, thanks for any help in the matter.
That's called grouping, the group by clause will let you do that, make sure you don't just pull out the count but also the thing you're counting, in this case ball.
Get the lowest number occurrences:
SELECT ball, COUNT(*) FROM mytable GROUP BY ball ORDER BY ball ASC limit 1;
Get the highest number occurrences:
SELECT ball, COUNT(*) FROM mytable GROUP BY ball ORDER BY ball DESC limit 1;
If you want them all in one result you can use a union/union all:
(SELECT ball, COUNT(*) FROM mytable GROUP BY ball ORDER BY ball ASC limit 1)
UNION ALL
(SELECT ball, COUNT(*) FROM mytable GROUP BY ball ORDER BY ball DESC limit 1);
you can simply use
SELECT column, COUNT(*)
FROM mytable
GROUP BY column_name
this will count all of the existing entries for the specific column_name
you should use column before COUNT(*) so you know what has that many values.
i hope this helps!

Getting Total Votes Form mysql table and Compare it?

I have a table with
id primary key, nominee_id, cat_id, user_id(voter id), vote_status, date
these fields, We have nominees for this voting process under different categories, so each nominees can be nimnated to more than one category. ok, all process is going well, I can take total count of votes got for each nominees in each category. but I dont have any idea How to get the winner from this table using SQL.
I want to get Most votes gained Nominees in each category, however as I said I can get total votes got for each nominees in each category using
SELECT nominee_id FROM voting WHEREcat_id= $cid.
Is it possible get this through another SQL statement, or else can anyone suggest any other way to get this.
below is the table, I want to get back the Nominee_id who got max Vote in a particulat cat_id, eg: in hte below table I want to get nominee_id 29 as a winner in cat_id 3, because he got two votes in that category
This query will give you the winner from each category.
SELECT nid, cid, max(votes) as final_votes from (select nominee_id as nid, cat_id as cid, count(user_id) as votes from voting group by cat_id, nominee_id) nv GROUP BY cid order by final_votes desc;
This one should work
SELECT nominee_id, COUNT(nominee_id) AS countNominee FROM voting WHERE
vote_status = 'yes' GROUP BY cat_id ORDER BY countNominee DESC

Get the list of ten top publishers in database

I've got following tables in my MySQL database:
USERS
iduser nick password
ARTICLES
idarticles iduser text
How can I get by one SQL query the list of e.g. 10 top publishers of articles ordering by the count of added articles? Is there any way to do that? I'm using PHP to ask database.
Yes, this should be quite easy via JOIN and COUNT(). Something like the following
SELECT `users`.`iduser`, COUNT(`articles`.`idarticles`) AS `total_articles`
FROM `users`
INNER JOIN `articles` ON `users`.`iduser` = `articles`.`iduser`
GROUP BY `users`.`iduser`
ORDER BY `total_articles` DESC
LIMIT 10
A little explaining:
COUNT() will get you what it says - a count of all relevant entries in articles
INNER JOIN will pair all entries that belong together (defined via ON)
GROUP BY tells SQL that you are interested in various results, each differing by iduser (without this, you'd get all articles counted in the first returned row)
ORDER BY .. DESC is important to get the result in a descending order (so most published first)
LIMIT 10 does exactly that

Include NULL as 0 in COUNT SQL Query

I know for a fact this has been asked a few times before, but none of the answered questions relating to this seem to work or are far too confusing for me..
I should probably explain.
I'm trying to create an AJAX script to run to order some results by the number of 'Likes' it has.
My current code is this:
SELECT COUNT(*) AS total, likes.palette_id, palette.*
FROM likes LEFT JOIN palette ON likes.palette_id = palette.palette_id
GROUP BY likes.palette_id
ORDER BY total DESC
Which works fine, however it doesn't list the results with 0 likes for obvious reasons, they don't exist in the table.
I've attached images of the current tables:
Likes table:
http://imgur.com/EGeR3On
Palette table:
http://imgur.com/fKZmSve
There are no results in the likes table until the user clicks 'Like'. It is then that the database gets updated and the palette_id and user_id are inserted.
I'm trying to count how many times *palette_id* occurs in the likes table but also display 0 for all palettes that don't appear in the likes table.
Is this possible? If so, can someone help me out at all?
Thank you
It might not be the exact MySQL syntax (I'm used to SQL Server), but should be pretty straight forward to translate if needed.
SELECT p.*, IFNULL(l.total, 0) AS total
FROM palette p
LEFT JOIN (
SELECT palette_id, COUNT(*) AS total
FROM likes
GROUP BY palette_id
) l
ON l.palette_id = p.palette_id
ORDER BY total
Try this:
SELECT COUNT(likes.palette_id) AS total, palette.palette_id, palette.*
FROM palette LEFT JOIN likes ON likes.palette_id = palette.palette_id
GROUP BY palette.palette_id
ORDER BY total DESC
EDIT:
In regards to the discussion about listing columns that are not in the GROUP BY, there's a good explanation in this MySql documentation page.
MySQL extends the use of GROUP BY so that the select list can refer
to nonaggregated columns not named in the GROUP BY clause. This means
that the preceding query is legal in MySQL. You can use this feature
to get better performance by avoiding unnecessary column sorting and
grouping. However, this is useful primarily when all values in each
nonaggregated column not named in the GROUP BY are the same for each
group. The server is free to choose any value from each group, so
unless they are the same, the values chosen are indeterminate.
In this example, the palette information not added to the GROUP BY will be the same for each group because we are grouping by palette_id so there won't be any issue using palette.*
Your join is written backwards. It should be palette LEFT JOIN likes, because you want all rows in palette and rows in likes, if they exist. The "all rows in palette" will get you a palette_id for the entries there without any matching "likes."

Categories