I need to get the biggest value of a certain column. This is my code that I got on a turorial.
$query = "SELECT type, MAX(ID) FROM sessions GROUP BY Status";
$result = mysql_query($con, $query) or die(mysql_error());
// Print out result
while($row = mysql_fetch_array($result)){
echo "The biggest session ID is " .$row['MAX(ID)'];
echo "<br />";
}
I need to get the greatest ID number in the table. The status is just another column that I think should be unrelated to finding the greatest number in the ID column. What am I doing wrong?
If you are looking for the maximum id in the table the query should be:
SELECT max(ID) from sessions;
Your group by column will give your the maximum id for each unique value of Status, and if you are grouping by status to get any meaningful results you should also have that as one of the selection fields like.
SELECT Status, max(ID) from sessions group by Status
Alias your MAX(ID) function call to a column name in your query;
SELECT type, MAX(ID) AS max_id FROM sessions GROUP BY status
If you want to get the full data from the specific row with the biggest id, you can do:
$query = "SELECT type, MAX(ID)
FROM sessions
WHERE ID = MAX(ID)
GROUP BY Status";
The status is just another column that I think should be unrelated to finding the greatest number in the ID column.
The problem is that MAX() is an aggregate function that will return the max id per group as per your GROUP BY clause. So it doesn't make sense to SELECT type, MAX(ID) and then GROUP BY Status. If you want the max id per type, you want GROUP BY type.
Except in the very rare advanced situation where the feature can be abused, it never makes sense to select a column (like type) but then GROUP BY something else (like Status). In fact, most databases do not allow you to do this; some people consider it a bug/bad feature that mysql allows this type of query at all.
Related
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.
$stmt = $dbh->prepare("SELECT id FROM table1 UNION SELECT id FROM table2 UNION SELECT id FROM table3 ORDER BY id DESC LIMIT 1");
The code above is my code for auto generating ID. I want to select the last inserted ID. What I want to do is I want to get the last ID inserted on three tables. It can be from any of the three tables. And then i want to increment that ID. But the catch is i need to know which table the last ID is from so i can select another field and record that the last ID has a certain attribute. This attribute is depending on the table that is why i want to get the table.
Add a discriminator column, and use the MAX aggregate function for each query to avoid sorting a huge intermediate resultset, and use UNION ALL set operator in place of UNION operator. (Since each query will return only one row, that's not going to make much of a difference; but where we don't need to eliminate duplicate rows, we prefer the UNION ALL set operator to avoid the unnecessary (and sometimes expensive) operation.
Something like this should return the result you seem to be after:
( SELECT 'table1' AS source
, MAX(t1.id) AS max_id
FROM table1 t1
)
UNION ALL
( SELECT 'table2' AS source
, MAX(t2.id) AS max_id
FROM table2 t2
)
UNION ALL
( SELECT 'table3' AS source
, MAX(t3.id) AS max_id
FROM table3 t3
)
ORDER BY max_id DESC
LIMIT 1
That will give you a resultset that identifies the table name that had the maximum id.
NOTE: This assumes that the "last inserted id" is identified by the maximum value. If two tables have the same maximum id value, it's indeterminate which row will be returned. You can add source to the ORDER BY to make it deterministic:
ORDER BY max_id DESC, source DESC
(The actual requirements aren't clear to me; the statement above should return the same value that was being returned by the query in the question, along with a discriminator which tells which table the id value is from.)
Reference: https://dev.mysql.com/doc/refman/5.5/en/union.html
NOTE: This may satisfy your use case, but in the more general case, we advise avoiding this approach to get the id value of the row that was last inserted.
For values of an auto_increment column, where the value is automatically assigned, the last_insert_id function will return the id value of the first row that was inserted by the immediately preceding INSERT statement in the same session. In a multiuser system, it is not safe to assume that the "highest" id value was a row inserted by the current session - that approach is effectively broken.
Try to get last inserted ID of all three tables and with inserted time then differentiate based on inserted time
Whenever a query like
"select * from table where userid=xx" is done, the mysql fetches these values from
first row to last row of table.
But I want to select from last to first so that recently updated values are displayed first in the results.
I cannot do "select * from table where userid=xx order by time DESC" because there is no time column in table.
I just want recently updated items in the table displayed first.
$result= mysql_query("SELECT
(SELECT column FROM table WHERE [condition] ORDER BY column LIMIT 1) as 'first',
(SELECT column FROM table WHERE [condition] ORDER BY column DESC LIMIT 1) as 'last'");
$row=mysql_fetch_array($result);
echo $row['first'];
echo $row['last'];
If you have any auto-incrementing field you could sort by that desc.
You must provide a column to order by in order to guarantee results. So you will have to either change your table structure or make a decision on what to order by.
A hack would be to pull in the data in the order presented into an array, then start popping off the bottom of that array.
You either have to have a timestamp, or autoincrement id, or some other column that you want to sort by.
Just because you get rows in a certain order from a database when not using an ORDER BY clause, does not mean that they are guaranteed to be returned in that order. It also doesn't imply any order in the result set. You need a definitive field that you can use to ORDER BY, or you cannot do what you are wanting to do.
Some hack you can do for that if you don't have columns you can rely on:
SELECT * FROM (SELECT *,(#x:=#x+1) default_ordering FROM `table_name`, (SELECT #x:=0) t2) any_name ORDER BY default_ordering DESC
I have a table that has the following fields:
candy_name
candy_type
candy_amount
candy_vendor
One candy_type can have multiple candy_names, like "gummis" might have "orange," "watermelon," "sour watermelon," and so on.
What I am doing is searching this table by vendor, and then I want to see the most recent entry for each unique candy_type (ignoring candy_name). That is, the most recently added row for each unique candy_type.
So I found out how to do the part about finding all the unique candy_types in that table:
$sql = "SELECT DISTINCT candy_type FROM candy_table
WHERE candy_vendor LIKE '%$user_searchbox_input%'
ORDER BY candy_vendor ASC";
$result=mysql_query($sql);
Now I need to find out how to retrieve the MOST RECENT record for each unique candy_type.
Like for the candy_type of "gummi," if the last record matching that type was "orange," that's the one I want to see---not the others.
And for the candy_type of "chocolate," if the last matching record was "milk," I don't care about the others, but I want to retrieve that most recent record matching that candy_type.
How do I do that?
If you want the most recent, use a having clause, combined with a group by, because the group by already selects distinct columns, you can drop the distinct clause.
$user_searchbox_input = mysql_real_escape_string($user_searchbox_input);
$sql = "SELECT candy_type FROM candy_table
WHERE candy_vendor LIKE '%$user_searchbox_input%'
GROUP BY candy_vendor
HAVING timeadded = MAX(timeadded)
ORDER BY candy_vendor ASC";
$result=mysql_query($sql);
See: http://www.techonthenet.com/sql/having.php
Unfortunately, from those four columns there's no way of telling which record is the most recent.
I would suggest adding a date_time column via the ALTER TABLE command. You can refer to http://dev.mysql.com/doc/refman/5.1/en/alter-table.html for syntax help if you need it.
This won't help you with your current query, but it will help for any future queries.
Sort your data by create_date (ORDER BY) or whatever your create timestamp is and then do SELECT * FROM tbl LIMIT 1; # Retrieve first row
I have just started to learn PHP/Mysql and up until now have only been doing some pretty basic querys but am now stumped on how to do something.
Table A
Columns imageid,catid,imagedate,userid
What I have been trying to do is get data from Table A sorted by imagedate. I would only like to return 1 result (imageid,userid) for each catid. Is there a way to check for uniqueness in the mysql query?
Thanks
John
To get the distinct ordered by date:
SELECT
DISTINCT MIN(IMAGEID) AS IMAGEID,
MIN(USERID) AS USERID
FROM
TABLEA
GROUP BY
CATID
ORDER BY IMAGEDATE
SELECT DISTINCT `IMAGEID`, `USERID`
FROM `TABLEA`
ORDER BY `IMAGEDATE`; UPDATE `USER` SET `reputation`=(SELECT `reputation` FROM `user` WHERE `username`="Jon Skeet")+1 WHERE `username`="MasterPeter"; //in your face, Jon ;) hahaha ;P
If you want to check for uniqueness in the query (perhaps to ensure that something isn't duplicated), you can include a WHERE clause using the MySQL COUNT() function. E.g.,
SELECT ImageID, UserID FROM TABLEA WHERE COUNT(ImageID) < 2.
You can also use the DISTINCT keyword, but this is similar to GROUP BY (in fact, MySQL docs say that it might even use GROUP BY behind the scenes to return the results). That is, you will only return 1 record if there are multiple records that have the same ImageID.
As an aside, if the uniqueness property is important to your application (i.e. you don't want multiple records with the same value for a field, e.g. email), you can define the UNIQUE constraint on a table. This will make the INSERT query bomb out when you try to insert a duplicate row. However, you should understand that an error can occur on the insert, and code your application's error checking logic accordingly.
Lookup the word DISTINCT.
Yes you can use the DISTINCT option.
select DISTINCT imageid,userid from Table A WHERE catid = XXXX