Find Duplicate Rows/Records from Table - php

Here is my table structure,
Im try run query
$sql = mysql_query("SELECT content,niche, COUNT(content) TotalCount FROM table_name GROUP by content HAVING COUNT(content)>=2");
I i think is give me corect result, but have problem to list result with php and make delete button to delete one of duplicated rows
Im get result in php
Content ID - Niche ID - TotalCount
208 - 2 - 2
210 - 32 - 3
But result should be
Content ID - Niche ID - TotalCount
208 - 2 - 2
208 - 2 - 2
210 - 32 - 3
210 - 32 - 3
210 - 32 - 3
im try result display with php
while($row = mysql_fetch_assoc($sql)) {
$array[] = $row;
}
foreach($array as $row) {
echo $row['content']." - ".$row['niche']." - ".$row['TotalCount']."<br>";
}

GROUP BY will collapse the results on the field you're grouping, in this case content - hence why you only see two results.
If you want to keep the GROUP BY technique, you can also use GROUP_CONCAT(niche) to pull a comma-separated list of each niche for a given content value:
SELECT
content,
GROUP_CONCAT(niche) AS niche,
COUNT(content) TotalCount
FROM
table_name
GROUP BY
content
HAVING
COUNT(content)>=2;
You can then use PHP's explode(',', $row['niche']) to get each distinct value and then use those to determine which one you want to delete.
foreach($array as $row) {
$niches = explode(',', $row['niche']);
foreach ($niches as $niche) {
echo $row['content'] . " - " . $niche . " - " . $row['TotalCount'] . "<br />";
}
}

I think this is what you're asking for, all duplicate rows (with row_id) and how many times they are duplicated;
SELECT a.row_id, a.content, a.niche, cnt
FROM table_name a
JOIN (
SELECT MIN(row_id) m, COUNT(*) cnt, niche,content
FROM table_name
GROUP BY content,niche
HAVING COUNT(*)>1
) b
ON a.niche=b.niche
AND a.content=b.content
An SQLfiddle to test with.

Make the following change in sql:
$sql = mysql_query("SELECT content,niche, COUNT(content) TotalCount FROM table_name HAVING COUNT(content)>=2");

Related

PHP Calculate rank from database

I got a little problem, I've got a database, in that database are different names, id, and coins. I want to show people their rank, so your rank has to be 1 if you have the most coins, and 78172 as example when your number 78172 with coins.
I know I can do something like this:
SELECT `naam` , `coins`
FROM `gebruikers`
ORDER BY `coins` DESC
But how can I get the rank you are, in PHP :S ?
You can use a loop and a counter. The first row from MySql is going the first rank,I.e first in the list.
I presume you want something like:
1st - John Doe
2nd - Jane Doe
..
..
right?
See: http://www.if-not-true-then-false.com/2010/php-1st-2nd-3rd-4th-5th-6th-php-add-ordinal-number-suffix
Helped me a while ago.
You could use a new varariable
$i = "1";
pe care o poti folosi in structura ta foreach,while,for,repeat si o incrementezi mereu.
and you use it in structures like foreach,while,for,repeat and increment it
$i++;
this is the simplest way
No code samples above... so here it is in PHP
// Your SQL query above, with limits, in this case it starts from the 11th ranking (0 is the starting index) up to the 20th
$start = 10; // 0-based index
$page_size = 10;
$stmt = $pdo->query("SELECT `naam` , `coins` FROM `gebruikers` ORDER BY `coins` DESC LIMIT {$start}, {$page_size}");
$data = $stmt->fetchAll();
// In your template or whatever you use to output
foreach ($data as $rank => $row) {
// array index is 0-based, so add 1 and where you wanted to started to get rank
echo ($rank + 1 + $start) . ": {$row['naam']}<br />";
}
Note: I'm too lazy to put in a prepared statement, but please look it up and use prepared statements.
If you have a session table, you would pull the records from that, then use those values to get the coin values, and sort descending.
If we assume your Session table is sessions(session_id int not null auto_increment, user_id int not null, session_time,...) and we assume that only users who are logged in would have a session value, then your SQL would look something like this: (Note:I am assuming that you also have a user_id column on your gebruikers table)
SELECT g.*
FROM gebruikers as g, sessions as s WHERE s.user_id = g.user_id
ORDER BY g.coins DESC
You would then use a row iterator to loop through the results and display "1", "2", "3", etc. The short version of which would look like
//Connect to database using whatever method you like, I will assume mysql_connect()
$sql = "SELECT g.* FROM gebruikers as g, sessions as s WHERE s.user_id = g.user_id ORDER BY g.coins DESC";
$result = mysql_query($sql,$con); //Where $con is your mysql_connect() variable;
$i = 0;
while($row = mysql_fetch_assoc($result,$con)){
$row['rank'] = $i;
$i++;
//Whatever else you need to do;
}
EDIT
In messing around with a SQLFiddle found at http://sqlfiddle.com/#!2/8faa9/6
I came accross something that works there; I don't know if it will work when given in php, but I figured I would show it to you either way
SET #rank = 0; SELECT *,(#rank := #rank+1) as rank FROM something order by coins DESC
EDIT 2
This works in a php query from a file.
SELECT #rank:=#rank as rank,
g.*
FROM
(SELECT #rank:=0) as z,
gebruikers as g
ORDER BY coins DESC
If you want to get the rank of one specific user, you can do that in mysql directly by counting the number of users that have more coins that the user you want to rank:
SELECT COUNT(*)
FROM `gebruikers`
WHERE `coins` > (SELECT `coins` FROM `gebruikers` WHERE `naam` = :some_name)
(assuming a search by name)
Now the rank will be the count returned + 1.
Or you do SELECT COUNT(*) + 1 in mysql...

SQL: can I JOIN 2 tables according the first table "array" value?

Im trying to find a better way to return 2 tables at once.
My first table is:
[ID] [area]
1 13,12,15
6 18,17,13
and the second table is:
[areaname] [singlearea]
textOf12 12
textOf18 18
textOf15 15
Now, I need to return for each [ID] hits area names, for example:
For the ID: 1, I need the following array: (textOf12,textOf15)
and for the ID 6 I need: (textOf18) only.
This is what i have for now (I don't think its a nice code):
$getall = "SELECT * FROM table1";
$resultfull = mysql_query($getall);
while ($res = mysql_fetch_assoc($resultfull))
{
$uarray = array();
$sqlarea = explode(",", $res['area']);
foreach($sqlarea as $userarea)
{
$areaarray = runquery("SELECT areaname From table2 WHERE singlearea = '".$userarea."'");
$value = mysql_fetch_object($areaarray);
array_push($uarray,$value->areaname);
}
var_dump($uarray);
any suggestions?
Thank you very much!
Comma separated ID list and ID value pretty good matching using like:
select t1.id, t2.areaname
from table1 t1, table2 t2
where concat(',', t1.area, ',') like concat('%,', t2.singlearea, ',%')
However It's recommended to use additional link table!

PHP fetch_array/sql without sorting values

SQL:
SELECT question,alt_1,alt_2,alt_3,alt_4 FROM questions WHERE id IN ('12','2','32','23')
PHP:
while ($questions = mysql_fetch_array($game)){
echo "$questions[question]";
}
I want the rows to be printed in the order the values are sent to sql: 12 - 2 - 32 - 23.
But fetch_array/sql(?) seems to sort the values so the order becomes the following: 2 - 12 - 23 - 32 (starts with the lowest number..)
Is there any way to stop the array from being sorted by numbers!?
USE FIND_IN_SET
SELECT question,alt_1,alt_2,alt_3,alt_4
FROM questions
WHERE id IN ('12','2','32','23')
ORDER BY FIND_IN_SET(id, '12,2,32,23')
Note FIND_IN_SET(id, '12,2,32,23') 12,2 without space
FIND_IN_SET(field, 'val1,val2')
Try yhis,
" ORDER BY FIELD(id'12','2','32','23')"
SQL: "SELECT question,alt_1,alt_2,alt_3,alt_4 FROM questions WHERE id IN
('12','2','32','23') ORDER BY FIELD(id'12','2','32','23')"
while($questions = mysql_fetch_array($game)){
echo "$questions[question]";
}

Join two MySQL Tables and display combined data

I have two tables in my database.
cat - catid, catname
articles - id, catid, content
so what i want to display is category name (catname) and how many articles are there in that category.
This is my code but it dosent work.
$query = "SELECT cat.cname, COUNT(articles.cat_id)".
"FROM cat, articles ".
"GROUP BY cat_id";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result)){
echo $row['cname']. " - ". $row['COUNT(cat_id)'];
echo "<br />";
}
Any help will be most aprriceated. thanks.
So this is a 1:many relationship. i.e. 1 Category -> Many articles.
The best way to do this is to create a third table, an adjacency list.
Keep your 'category_id' and 'article_id' unique in tables 'cat' and 'article'.
In your third table you define the 1 : many relationships.
Table 3: cat_articles
adj_id cat_id art_id
1 1 1
2 1 2
3 2 3
4 2 4
5 3 5
Now join the tables:
$sql = "SELECT * FROM `cat_articles` adj ".
"LEFT JOIN (`cat` cat, `articles` art)".
"ON (cat.cat_id = adj.cat_id AND art.art_id = adj.art_id) ";
This takes the adjacency table, preserves it's format(due to left join) and appends the tables article and category to it, giving you a categorised table of all your articles. You can now use mysql_fetch_array() to get your results.
Edit: reference first comment, displaying number of rows
You can either, as you have done, use SQL's function COUNT to return a count of a specific column.
Or, with PHP, run the query, and then use mysql_num_rows($result) to return the number of rows SQL has in its buffer.
Alternatively, retrieve results using mysql_fetch_array($result) and use count to return the number of paired values in the array.
Using mysql_fetch_array:
$query = "SELECT cat.cname, COUNT(articles.cat_id)".
"FROM cat, articles ".
"GROUP BY cat_id";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result)){
echo $row[0]. " - ". $row[1];
echo "<br />";
}
mysql_fetch_array returns a number indexed array (0,1,2,3,4, ..)
SELECT cat.cname, COUNT(articles.cat_id) artcount
FROM cat, articles WHERE c.cat_id = articles.cat_id
GROUP BY cat.cat_id
I guess you are missing the join clause. Unless you are joining the tables correctly you are creating a "cartesian product".
Get the rows "$row['cname'] and $row['artcount'].

Mysql array and data

Mysql query and PHP code that I'm using to get users from the database that meet certain criteria is:
$sql = mysql_query("SELECT a2.id, a2.name FROM members a2 JOIN room f ON f.myid = a2.id
WHERE f.user = 1 AND a2.status ='7' UNION SELECT a2.id, a2.name FROM members a2
JOIN room f ON f.user = a2.id WHERE f.myid = 1 AND a2.status ='7' GROUP BY id")
or die(mysql_error());
while ($r = mysql_fetch_array($sql))
{
$temp[] = '"'.$r[0].'"';
}
$thelist = implode(",",$temp);
The query that follows get the list of members with new galleries by using array from the previous query.
$ft = mysql_query("SELECT id, pic1 FROM foto WHERE id IN ($thelist) AND
pic1!='' ORDER BY date DESC LIMIT 10");
while ($f = mysql_fetch_array($ft))
{
echo $f['id']." - ".$f['pic1']."<br/>";
}
These queries working fine but I need to get the name for every user listed in second query. This data is in the first query in the column name. How can I get it listed beside '$f['id']." - ".$f['pic1']'?
While I might just alter the first query to pull the galleries at the same time, or change the second query to join and get the name, you could keep the same structure and change a few things:
In the loop after the first query when building $temp[], also build a lookup table of user id to user name:
$usernames[$r[0]] = $r[1];
Then in your output loop, use the id (assuming they are the same!) from the second query to call up the user name value you stored:
echo $f['id'] . " - " . $f['pic1'] . " - " . $usernames[$f['id']] . "<br/>";

Categories