Select last record in the table - php

How to select last record (that is having MAX(id)) from the table?
Next statement works OK, but selects the first record:
$statistics = SystemStatisticsHistory::findOne(1);

To get the model with max id you can apply reverse order and limit to one.
SystemStatisticsHistory::find()->orderBy(['id' => SORT_DESC])->one();
Another option is to use subselect with max like so:
SystemStatisticsHistory::find()
->where(['id' => SystemStatisticsHistory::find()->max('id')])
->one();
There are some nuances using last option, check this question.
You can check the documentation for max() here.
I personally prefer using first variation.
To get the first record, just change the order direction to SORT_ASC in first query and max() to min() in second query.
P.S. Hardcoded id is a bad practice.

Optimised one
SystemStatisticsHistory::find()->select(['id'=>'MAX(`id`)'])->one()->id;
OR if you want increase by number
SystemStatisticsHistory::find()->select(['id'=>'( MAX(`id`)+ 1) '])->one()->id;

Related

Laravel return one record where max value

I'm trying to return one record with a max value as an object. When I do this:
public function highestExpense()
{
return auth()->user()->expenses()->max('amount');
}
It works, and I get the highest value. But I want to have the whole record returned, so I also have access to the expense name, created_at, and so on.
This didn't work for me:
return auth()->user()->expenses()->max('amount')->get();
It seems like a simple solution but the answer is nowhere to be found.
If I'm understanding your question correctly, to get the record that has the highest amount you could just add an orderBy and the grab the first row:
auth()->user()->expenses()->orderBy('amount', 'desc')->first();
This should give the expense with the highest amount.
Hope this helps!
You can use the Collection method sortByDesc as follows :
return auth()->user()->expenses()->sortByDesc('amount')->first();
Normally,
This is your try,
return auth()->user()->expenses()->max('amount')->get();
This will work in Normal case where there is only one maximum value of amount column in the table.
So long as there isn't a collision with the max column and another column within the table, this might work.
If there are more than one maximum value this will not work.
So, As Ross Wilson said above, You have to order the rows in descending order and get the first row like:
auth()->user()->expenses()->orderBy('amount', 'desc')->first();
This will work perfectly because even if there are more than one max, this will give first row with maximum value of the column amount.

Using levenshtein in MySQL search for one result

I am trying to do a search on my MySQL database to get the row that contains the most similar value to the one searched for.
Even if the closest result is very different, I'd still like to return it (Later on I do a string comparison and add the 'unknown' into the learning pool)
I would like to search my table 'responses' via the 'msg1' column and get one result, the one with the lowest levenshtein score, as in the one that is the most similar out of the whole column.
This sort of thing:
SELECT * FROM people WHERE levenshtein('$message', 'msg1') ORDER BY ??? LIMIT 1
I don't quite grasp the concept of levenshtein here, as you can see I am searching the whole table, sorting it by ??? (the function's score?) and then limiting it to one result.
I'd then like to set $reply to the value in column "reply" from this singular row that I get.
Help would be greatly appreciated, I can't find many examples of what I'm looking for. I may be doing this completely wrong, I'm not sure.
Thank you!
You would do:
SELECT p.*
FROM people p
ORDER BY levenshtein('$message', msg1) ASC
LIMIT 1;
If you want a threshold (to limit the number of rows for sorting, then use a WHERE clause. Otherwise, you just need ORDER BY.
Try this
SELECT * FROM people WHERE levenshtein('$message', 'msg1') <= 0

Why does mysql_num_rows return 1 for a SELECT on an empty table?

The code:
$review = mysql_query("SELECT conceptID, MIN(nextReview) FROM userconcepts WHERE userID='$userID'");
$nrows = mysql_num_rows($review);
echo "$nrows<br />\n";
The query works when the table has such entries and returns the correct column values. However, when the table is empty, as I can confirm right now in HeidiSQL, mysql_num_rows still returns 1, but the column values are empty. (The problem still remains if the table has other values for different userIDs).
I expect this query to return the empty set sometimes during normal operations, and I want to take action based on the existence of a result, but I also want to use the result if it exists. Any idea why this code is not working as I expect it to work (I expect it to return 0 if the table is empty)?
First of all, the query has a very simple problem: you're showing the conceptID field, but not grouping by it. If you want to show a field on a SELECT that uses aggregate functions, you should show it; not doing so is an error, and will make many engines not execute your query.
That aside, whenever you have an aggregate function, and you don't group by anything (i.e., don't add a GROUP BY clause), the result is one row. Regardless of the amount of rows in the table.
The reason why is because when a SQL engine executes a query with only aggregation functions, then it returns one row. So:
select count(*)
from table
where 1 = 2
is going to return 1 row with the value 0. This is the way that all SQL engines work.
Your query is a little different:
select conceptID, MIN(nextReview)
FROM userconcepts
WHERE userID='$userID'"
In most SQL dialects, you would get an error of the from "conceptID not in group by clause" or something like that. That is, the query would have a syntax error.
MySQL supports this. It will return the minimum value of nextReview (from the rows that meet the where condition) along with an arbitrary value of conceptID (from those same rows). In this case, there are no rows, so the values will be set to NULL.
Perhaps, you want one row per conceptId. That query would be:
select conceptID, MIN(nextReview)
FROM userconcepts
WHERE userID='$userID'
group by conceptId

mysql_fetch_array() and output in chunks

So I have a table with 45 records (but can be dynamic) and I use mysql_fetch_array() to get the data from the database. What is the best way to output 5 records at a time? So I need to do record 1-5, then have a link for records 6-10, 11-15, and so on. I thought about doing something with array_chunk but not sure how to keep track of the record number. Thanks for hints.
To get the first 5 results form a table:
SELECT * FROM table ORDER BY table.column_name ASC LIMIT 0, 5
Selects from `table`
Ordered by the column name Ascending
Limit 0,5 selects the first 5 results, starting at 0.
Change LIMIT 0,5 to 5,5 to list results 6-10 (start at record 5, and continue for 5 records.)
Ordering is just good practice to ensure consistency. Under most circumstances set this to 'id' if you have an auto-increment 'id' column. If you want results sorted by date, order by a timestamp column. If you want data reversed, order by DESC.
You can keep track of where your queries are though PHP Sessions, Passing GET parameters, temporary database tables, and probably a few more I missed.
Other solution:
Use the array returned from the mysql_fetch_array() and utilite http://php.net/manual/en/language.types.array.php
The obvious disadvantage to this approach is the fact that it fetches all rows in the table. This is okay if you'll NEVER have more than a manageable number of rows. In your case, 45 should be fine, assuming they're not gigantic rows. This approach may also may useful if you want data pre-loaded.
I'd suggest using limits and incremental offsets in your query. Your first query would then be:
select * from TABLE limit 0,5;
Your link has a parameter referencing the next offset so the next query would be:
select * from TABLE limit 5,5;
And so on.
You need in your query LIMIT 0,5. Search web for php paginator.

Echoing a pseudo column value after a COUNT

Please don't beat me if this is elementary. I searched and found disjointed stuff relating to pseudo columns. Nothing spot on about what I need.
Anyway... I have a table with some rows. Each record has a unique ID, an ID that relates to another entity and finally a comment that relates to that last entity.
So, I want to COUNT these rows to basically find what entity has the most comments.
Instead of me explaining the query, I'll print it
SELECT entity_id, COUNT(*) AS amount FROM comments GROUP BY entity_id ORDER BY amount DESC
The query does just what I want, but I want to echo the values from that pseudo column, 'amount'
Can it be done, or should I use another method like mysql_num_rows?
Thank you!!!
It's just the same as with the other column – you use the mysql_fetch_* family.
Note that moving to the Mysqli extension is encouraged. See here why.
Once you have the row in, say, $row, you can simply use the value of $row['amount'].

Categories