PHP - MySQL - GROUP BY / ORDER BY? wrong results output - php

I am rather new to MySQL, I have this problem, which I have searched for help with, but could not find the answer (possibly because I am not sure what to search for). I am sure there is a simple solution.
I have a simple MySQL table like this:
id | referenceid | status
40 104702 4
39 104720 2
38 104720 0
37 104719 2
36 104719 0
35 104702 2
34 104702 0
41 104719 5
I want to fetch an array that will produce the following output:
For each unique "referenceid" field, I want to know the highest "ID" (ie most recent) and its "Status".
So I have tried this query:
$result = mysql_query(
"SELECT status,id,referenceid
FROM image_status_tracking
GROUP BY referenceid",$db);
while ($row = mysql_fetch_array($result)) {
$id = $row['id'];
$status = $row['status'];
$referenceid = $row['referenceid'];
echo "ID $id, REFID $referenceid, Status $status <br />";
}
which gives this output:
ID 40, REFID 104702, Status 4
ID 37, REFID 104719, Status 2
ID 39, REFID 104720, Status 2
But this is not the result I was hoping for. The ID and Status for referenceid 104719 should be 41 and 5, not 37 and 2.
I cannot work out how to get the most recent ID line output for each referenceid.
Something I noticed, in PHPMYADMIN, (and you can see in the table above), the IDs are listed in reverse order, with the latest ID at the bottom. I am not sure if that is relevant to this problem.
I hope this is clear, I am sure it is a simple matter.
Thank you for reading.
James

Typing from memory so you might have to correct the syntax a little bit but the concept, i think, should work.
select *
from image_status_tracking
where id in (
select max(id) from image_status_tracking
GROUP BY referenceid
)

Your query does not do what you want it to do. For each reference id, it is selecting a random id and status. This is a (mis)Feature of MySQL called Hidden Columns.
What you want is more like:
select ist.*
from image_status_tracking ist join
(SELECT referenceid, max(id) as maxid
FROM image_status_tracking
GROUP BY referenceid
) r
on ist.referenceid = r.referenceid

Try this...
SELECT MAX(ID), Status From image_status_tracking
GROUP BY referenceid

Related

How to get the next row in sql

I have a table that is something like this
id | names | value
1 Vicky 43
2 Erica 23
3 Rueben 33
4 Bob 54
5 Chris 60
Then I set them in order according to their value. Now the table looks like this.
id | names | value
5 Chris 60
4 Bob 54
1 Vicky 43
3 Rueben 33
2 Erica 23
Now the starting point is id 5 which has a name of Chris and a value of 60. My goal is, to get the next row which has an id of 4 and name of Bob and a value of 54.
You just need to limit the resultset:
SELECT * from table
ORDER BY value DESC
LIMIT 1, 1
Output:
| ID | NAMES | VALUE |
|----|-------|-------|
| 4 | Bob | 54 |
Fiddle here.
The LIMIT basically works this way: the first number sets the starting point (being 0 the minimal value) and the second number the amount of items to fetch (in this case only one).
Edit:
A different way of understanding the question would be: Given a value for a particular field (EG: id field with value of 5)... what would be the previous record? As we have the id 4 in the data we should return that one.
That could be accomplished this way:
SELECT * from t
WHERE id < 5
ORDER BY id DESC
LIMIT 1
Fiddle here.
This way you can traverse the results in both orders (ASC and DESC) and also get both the next or previous (> or <) rows.
If your current ID is for example 4 then
Next:
select * from foo where id = (select min(id) from foo where id > 4)
previous:
select * from foo where id = (select max(id) from foo where id < 4)
sql server:
with temp as
(
SELECT ROW_NUMBER() OVER (ORDER BY value desc) AS ROWID, * FROM table_name
)
SELECT * from temp where ROWID=2
mysql:
SELECT * from table
ORDER BY value DESC
LIMIT 1, 1
I get the feeling that this is a PHP related question?
If that's so, then you can use PHP's mysql or mysqli_fetch functions to get what you want... along with a loop
This is your basic loop-through-a-mysql-query
$sql = mysql_query( "SELECT * from table ORDER BY value DESC" );
while ( $r = mysql_fetch_array( $sql ) ) {
echo $r['value'] . "<br />\n";
}
If you want to have them all at your disposal and be able to call either one of them at will, you will need to store the data in an accessible array, like so
$sql = mysql_query( "SELECT * from table ORDER BY value DESC" );
$theData = array();
while ( $r = mysql_fetch_array( $sql ) ) {
$theData[] = $r['value'];
}
Then, to access the SECOND value, use this
echo $theData[1];

MYSQL Select; I cannot figure out how to exclude rows based on a different column value

Table:
id value
100 1
101 1
102 1
102 0
103 1
I want the selection to return id's 100,101,103; that is, if the same id has two rows, one with value=1 and a second with value=0, I want to exclude it.
Appreciate any help.
Try this:-
Select id From table Group By id Having count(*) = 1
Could use the having MySQL construct:
SELECT id, count(*) AS tehCount FROM table GROUP BY id HAVING tehCount = 1;
Try this:
SELECT * FROM
table
GROUP BY id
HAVING COUNT(*) = 1

Counting number of times a value occurs and sending count to another column?

I have a table that I have fed data into through a PHP script, and am managing it using phpMyAdmin. My table has 4 columns. The first is an auto increment, second and third are values being fed in, and the final is meant to keep track of how many times the value from column 3 has appeared.
This is how my table currently appears
RowNumber UserID SongID Plays
1 540 2191 0
2 540 2671 0
3 550 3891 0
4 550 2191 0
5 550 2671 0
6 560 9391 0
7 560 2191 0
I want to search through the whole table and change the value in the Plays column to show how many times the value appears in the table.
Ideally, this is how I want my table to output:
RowNumber UserID SongID Plays
1 540 2191 3
2 540 2671 2
3 550 3891 1
4 550 2191 3
5 550 2671 2
6 560 9391 1
7 560 2191 3
Is there a way to search through the table and update these values?
The amount of data being inputted into the table is quite large, so an efficient solution would be greatly appreciated.
Consider using a view instead of a table, unless you need the value cached for performance reasons. You can compute the count of each value in a subquery and join the results back to the table like so:
SELECT Table.RowNumber, Table.UserID, Table.SongID, x.Plays
FROM Table
INNER JOIN (
SELECT SongID, COUNT(*) AS Plays
FROM Table
GROUP BY SongID
) x
ON Table.SongID = x.SongID;
And create a view from it using CREATE VIEW TableWithPlays AS SELECT .... Having an index on SongID will allow the subquery to complete rather quickly, and you will never have to worry about the Plays column being up to date.
If you do in fact want to cache the values, use an UPDATE query based on the above query:
UPDATE Table a
INNER JOIN (
SELECT SongID, COUNT(*) AS Plays
FROM Table
GROUP BY SongID
) b
ON a.SongID = b.SongID
SET Plays = b.Plays;
As with the view solution, don't forget the index on SongID.
I think you can use simple PHP query that is run periodically (Note: not an actual code):
$sql = "SELECT UserID, SongID, COUNT(RowNumber) AS CNT FROM SomeTable GROUP BY 1, 2 ORDER BY 3 ASC";
foreach($result as $row){
$sql = "UPDATE SomeTable SET Plays = ".$row['CNT']." WHERE UserID = '" . $row['UserID'] . "' AND SongID = '" . $row['SongID'] . "'";
}

MYSQL returning duplicate rows

I have a Database table in MYSQL, it looks like this:
Project_ID user_ID name
11 1 fred
11 2 rick
11 1 fred
I want to get the names in the table, but when I display it I get the same name twice because the user_ID 1 appears twice in the table. I tried to display it with GROUP BY and SUM, but I don't want to do it this way. How do I get it not to return duplicate rows?
Use DISTINCT
SELECT DISTINCT user_ID
, verschil_ma
FROM project_uren
WHERE project_ID = 11
GROUP BY user_ID
Point 1 is that should the user be assigned to the project twice?
Point 2 - Use the DISTINCT keyword to return only unique records - http://dev.mysql.com/doc/refman/5.0/en/distinct-optimization.html
SELECT DISTINCT user_ID
FROM TABLE
WHERE Project_id = 11
That will return you 1 and 2 (You won't get 1 twice)
Thanks
$results = // query
$results = array_unique($results);

summing two columns total in mysql

I want a resultset for this table:
ID Number_of_posts Number_of_user
1 100 21
2 23 34
as
ID Number_of_posts Number_of_user Number_of_posts_AND_Number_of_user
1 100 21 178
2 23 34 178
-----------------------------------------------
123 55
Is it possible to get the sum of two colums as another column/ as output in mysql?
To get cross-tab totals (horizontal and vertical):
select id,
number_of_posts as p,
number_of_users as u,
number_of_posts+number_of_users as p_and_u
from tbl
union all
select 99999 as id,
sum(number_of_posts) as p,
sum(number_of_users) as u,
sum(number_of_posts+number_of_users) as p_and_u
from tbl
order by 1
This will give you:
id p u p_and_u
----- --- --- -------
1 100 21 121
2 23 34 57
99999 123 55 178
You're complicating your query needlessly and using more memory that you have to. Pull the records in one query, then make another query to get the aggregates.
I know it doesn't answer your question, but it's what you should be doing instead. =)
SELECT id, number_of_posts, number_of_user,
(
SELECT SUM(number_of_posts + number_of_user)
FROM mytable
)
FROM mytable
SELECT SUM(Number_of_posts), SUM(Number_of_user) FROM table;
SELECT *,
(SELECT SUM(Number_of_posts) + SUM(Number_of_user) FROM TABLE) AS total
FROM table;
(Edit: Didn't originally notice it was the total total in the last column.)
Does MySQL support ROLLUP?
SELECT id,
SUM(Number_of_posts) Number_of_posts,
SUM(Number_of_user) Number_of_user,
SUM(Number_of_posts) + SUM(Number_of_user) Number_of_posts_AND_Number_of_user
FROM table
GROUP BY ROLLUP(id)
Edit: based on a quick search, in MySQL the last line might be GROUP BY id WITH ROLLUP.

Categories