Get last 5 item of sql results with Propel - php

I want to get the last 5 items of my search action. An example:
$quizzes = $user->getQuizs();
Now I would like to select the last 5 of that, is this possible with propel?
I tried ->getLast(5) but that's not correct.
Let's say I get 30 quizzes back, ordered by ID. I want to select the last 5 (with the highest id's .., these are the ones last created).

Easy peasy:
$quizzes = QuizQuery::create()->
filterByUser($user)->
orderByCreatedAt(\Criteria::DESC)->
limit(5)->
find()
;
This assumes you have a created_at column in your quiz table. You can then add this to your User model if you wish:
public function getLastQuizzes($limit = 5)
{
return QuizQuery::create()->
filterByUser($this)->
orderByCreatedAt(\Criteria::DESC)->
limit($limit)->
find()
;
}

Related

How can I add a css class to the 10 last entries of a mysql database?

I have a very simple PHP function, fetching all results (from two tables "Items" and "Categories" and displaying them on a single site (directly on index.php)
function fetchAllItems($pdo)
{
$statement = $pdo->prepare('select Items.*, Categories.*
from Items
INNER JOIN Categories ON Items.ItemCategoryID = Categories.id
ORDER BY Items.ItemName ASC'
);
$statement->execute();
return $statement->fetchAll(PDO::FETCH_CLASS, 'Item');
}
Now I want to add an icon to the left with css to the newest (= 10 last sql database entries / rows), but I don't know how to do.
As a PHP newbie my logic goes like this:
Identify the highest id
Subtract the number 10 of the above result / value
Create an if-function that goes something like this: "if $highest_id = within the range of 'lastInsertId() - 10' then apply css-class 'new-item'" (sorry for writing this down like a sentence, not like a real if-function, but as mentioned I am new...)
But I don't really know where to start / go from here and googling for the last 3.15 hours did not bring me any further?!
Thank you.
You can't simply subtract 10 from the highest ID to get the 10th highest, because there can be gaps in the ID sequence.
To get the 10 highest IDs, use:
SELECT id
FROM Items
ORDER BY id DESC
LIMIT 10
Put these into an array $first_10, and then when you're displaying the results of fetchAllItems you can do:
if (in_array($row->id, $first_10) {
$class = "newest";
} else {
$class = "";
}

PHP While: prevent looping rows where one field is identical to another

I'm using a while loop to get some data from my database, however the problem I have is that it's looping everything inside it (as expected from the start) but now I wonder if it's possible for it to search for duplicated, and skip those? Depending on if a field is identical.
Let's say 3 rows are being looped, everyone have the field "number" but only the first 2 rows has the same value in the field "number". I want it to only loop the first one, and then skip the 2nd one as it already has the same value in the "number" field as the previous one. Is it possible?
$q = $database->query("SELECT * FROM table1 ORDER BY id DESC LIMIT 7");
while($f = $q->fetch_array()) {
echo $f["number"] . "<br />";
}
you can avoid duplicated elements on mysql by adding the DISTINCT keyword after select
SELECT DISTINCT id,nom,prenom FROM matable

What is the most efficient way to exclude records with a particular ID in a MySQL query for random records?

I have an api endpoint that returns X amount of random posts from a table called "posts". This endpoint is used by a mobile app. It retreives random posts by doing a SELECT COUNT(*) on the posts table and returning the amount of posts in the table. It then enters a for loop in which, at the start of each loop, a random number from 0 to the COUNT(*) is generated. A random post is then obtained using the handy OFFSET. This for loop goes until X amount of random posts obtained.
pseudocode:
FUNCTION getRandPosts :
$numOfPosts = queryExecute("SELECT COUNT(*) from posts");
for (iterations < numOfRandomPostsNeeded) {
$randomNumber = rand(0, $numOfPosts)
$randomPost = queryExecute("SELECT * from posts LIMIT 1, OFFSET $randomNumber")
}
Now, for each call to a getRandPosts function I want them to always retrieve a unique post that wasn't retrieved before. For this current getRandPosts call AND FOR PASTS CALLS.
I've thought of several ways of going about doing this:
I could store the ID's of already seen posts in an array IN the app and then send this array to the getRandPosts function. The getRandPosts function then uses a "NOT IN" clause.
FUNCTION getRandPosts(ARRAY $idsOfPostsAlreadySeen) :
...
for ...
$randomPost = queryExecute("
SELECT * from posts
WHERE id NOT IN $idsOfPostsAlreadySeen
LIMIT 1, OFFSET $randomNumber")
$idsOfPostsAlreadySeen.addToArray($randomPost.id)
...
After each random post is retrieved, save that post id to a table called "seenPosts" where there is also a column called idOfApp which is used to distinguish users.
FUNCTION getRandPosts(STRING appInstallID) :
...
for ...
$randomPost = queryExecute("
SELECT posts.* FROM posts
JOIN seenPosts.postID FROM seenPosts
ON posts.id = seenPosts.postID
WHERE seenPosts.postID = null AND seenPosts.appInstallID = $appInstallID
LIMIT 1, OFFSET $randomNumber")
queryExecute("INSERT INTO seenPosts SET postID = $randomPost.id, appInstallID = $appInstallID")
...
I'd also like to ask about the idea of, for idea number one, creating a temporary table from the array and using JOIN with that temp table vs using the array.
Consider the idea that, at most, 600 posts will have to be excluded for any given user (so an array of 600 ids in the case of the first idea).

Running two queries with Datamapper in Codeigniter

I want do perform two queries, one to get the count of all results and one to get the actual results 9 by 9. My problem is when I try to get the count of the results: The second query gets all the 9 rows from database without the WHERE clause.
$courses = $this->load->model("course")->where("deleted",0);
$courses->where("country",strtolower($country));
$courses->count(); // returns 15
$courses->offset(($per_page)*9)->limit(9);
$courses->get(); // returns 9 rows from all database (like select * from courses limit 9) without where country=france
My problem is I want to count all the results but I want to get just 9 results for pagination purposes
Help needed for newbie codeigniter user
class Course extends DataMapper {
var $table = 'course';
var $error_prefix = '<li>';
var $error_suffix = '</li>';
function __construct($id = NULL) {
parent::__construct($id);
}
}
As far as I know, you must perform two queries agaisnt the database:
One for counting.
One for retrieving the results you want.
Your problem is you think the active records is keeping your results. When you perform a count, Datamapper will return you the results of the query and will be ready for a new query, so, it's not keeping the where clause.
Try doing it in two steps. For counting:
$courses = $this->load->model("course")->where("deleted",0);
$courses->where("country",strtolower($country));
$counting = $courses->count(); // returns 15
For retrieving results:
$courses = $this->load->model("course")->where("deleted",0);
$courses->where("country",strtolower($country));
$courses->offset(($per_page)*9)->limit(9);
$results = $courses->get(); // returns 9 rows from all database (like select * from courses limit 9) without where country=france

show row only 100 times PHP

How can I make a limit of showing the results? I need to limit it for 100 views.
In DB I have:
ID|NAME|PAGE|COUNT|DATE
In count I want to count untill 100 and then stop showing that ID. I could do it with count < 100. And then update the specific ID. I could get records with less than 100 views, but I couldn't manage to update count on the specific ID.
Row is showed with:
php code:
foreach($bannerGroups[0] as $ban) {
echo '<li class="right1">'.$ban->html().'</li>';
}
But I just don't know where to put the update in there. I tried, but all I got was to update only one ID. But it shows 4 on one page and randomizes them on refresh. So I don't know what to do.
Also I would like to say I am only learning php. Sorry for all the mess.
Code at http://pastebin.com/A9hJTPLE
If I understand correctly, you want to show all banners that have been previously-displayed less than 100 times?
If that's right, you can just add that to your WHERE clause:
$bannerResult = mysql_query("SELECT * FROM table WHERE page='cat' WHERE `COUNT` < 100");
To update them all, you can either run a query while displaying each individual banner, or "record" the id of each and run a single query at the end, like:
$ids = array();
foreach($bannerGroups[0] as $ban) {
$ids[] = $ban['ID']; // record the ID; don't know how Banner
// class works, assuming uses indexes; maybe ID() method?
echo '<li class="right1">'.$ban->html().'</li>';
}
...
mysql_query('UPDATE table SET `COUNT` = `COUNT` + 1 WHERE ID IN (' . join(',', $ids) . ')');
UPDATE:
Based off of a comment, your Banner class doesn't have a method to retrieve the individual banner's ID. In this case, you can record the ID values when you're building your banners array:
$ids = array();
while($row=mysql_fetch_assoc($bannerResult)) {
$banners[] = new Banner($row);
$ids[] = $row['ID']; // record the ID
}
// update the `count` on each record:
mysql_query('UPDATE table SET `COUNT` = `COUNT` + 1 WHERE ID IN (' . join(',', $ids) . ')');
sorry, but I got your question wrong...
first you have to insert a new sql-column like "viewcount" to the db...
on every read, you have to increment the value in viewcount...
for that behaviour (because, mysql does not allow sub-selects on update-clause on the same table), you have to fetch the results from db, as you do that, and pass all the primary-keys of the records to an array...
after the view-logic you have to fire up a query like:
UPDATE foo SET viewcount = viewcount + 1 WHERE id IN (1,2,3,4,5,6...,100);
where the IN-clause can be easily generated using your primary-keys-array with "implode(',', $arr);"
hope this helps.
$bannerResult = mysql_query("SELECT * FROM table WHERE page='cat' AND `count`<100");
#newfurniturey figured it out. in each foreach($banneruGroups added: $ids = $ban->getValue('id'); and then mysql_query("UPDATE dataa SET COUNT = COUNT + 1 WHERE id = '$ids'"); but is there any way to update them by adding query only once? And if the id is showed already 100 times i get Warning: Invalid argument supplied for foreach() in. Any idea how to fix it? I have 4 ids in DB . If one of them already have 100 views (count) then i get error!
Try to limit your data source for 100 items.
It's like OFFSET x LIMIT 100 in MySQL/PostgreSQL query or TOP 100 in MSSQL.

Categories