php mysql RAND() in foreach loop - php

I made page with all profiles. Every 3 rows I inserting a Premium block between results. I have 12 rows on page and 4 premium blocks between every 3 rows. I need to show random users with premium='1' row from mysql every foreach loop.
$sth = $db->prepare("SELECT count(*) as premiumCount FROM users WHERE premium='1'");
$sth->execute();
$answer = $sth->fetch();
$premium = $answer['premiumCount'];
$sth2 = $db->prepare("SELECT * FROM users WHERE active='1' AND block='0' ORDER BY premium DESC LIMIT 12");
$sth2->execute();
$result = $sth2->fetchAll();
foreach ($results as $answer) {
// getting user info
if ($premium > 0) {
$sth = $db->prepare("SELECT * FROM users WHERE premium='1' ORDER BY RAND()");
// getting premium user info
}
}
This code is work, but it can be 2-3 same premium blocks on page (I need 4 different blocks).

Select as many random premium users as you need before the loop with one query (you can add LIMIT 4 to your query) instead of selecting repeatedly inside the loop. That way you can be sure you won't have duplicates.
Fetch the results and store them in an array, and where you're running the "SELECT * FROM users WHERE premium='1'... query inside the loop, use a value from the array instead. You can use array_pop to get values so you won't have to mess with a counter or anything like that to keep track of your position in the array.
// getting premium user info
$sth = $db->prepare("SELECT * FROM users WHERE premium='1' ORDER BY RAND() LIMIT 4");
$sth->execute();
$premium = $sth->fetchAll();
foreach ($results as $answer) {
// getting user info
if ($premium) {
$premium_row = array_pop($premium);
}
}

Related

Creating a meet the team page, want to order by descending level and each level onto new row

I'm developing a Meet the Team page for my website. Here's how it looks so far (http://prntscr.com/gynyrj).
As you can see, it's in descending order. But, what I'm trying to achieve is so that each new level would go onto the next row. e.g. administrators level 7 at the top, administrators level 6 on the next row, administrators level 5 on the next and so on..
Something like this (http://prntscr.com/gyo1pc)
$query = $con->prepare("SELECT * from playerdata WHERE pAdmin >= 1 ORDER BY
`pAdmin` DESC");
$query->execute();
while($data = $query->fetch())
{
...panel code
}
Regards,
Daniel
Here's one possible solution. Create a 2D array that stores the $data arrays in your loop, using pAdmin as the first dimension's key:
$query = $con->prepare("SELECT * FROM `playerdata` WHERE `pAdmin` >= 1 ORDER BY `pAdmin` DESC");
$query->execute();
$playersByAdminLevel = array();
while($data = $query->fetch()) {
$adminLevel = $data['pAdmin'];
$playersByAdminLevel[$adminLevel][] = $data;
}
You can now do a nested loop over the $playersByAdminLevel array:
foreach($playersByAdminLevel as $players) {
foreach($players as $player) {
// $player['name'] etc.
}
echo '<br>\n'; // ... or whatever html you need to start the next row
}

how to use PHP function to get ranks for multiple columns in a table more efficent

I am trying to get single rank for a user for each stat "column" in the table. I am trying to do this as more efficiently because i know you can.
So I have a table called userstats. in that table i have 3 columns user_id, stat_1, stat_2, and stat_3. I want to me able to get the rank for each stat for the associated user_id. with my current code below i would have to duplicate the code 3x and change the column names to get my result. please look at the examples below. Thanks!
this is how i currently get the rank for the users
$rankstat1 = getUserRank($userid);
<code>
function getUserRank($userid){
$sql = "SELECT * FROM ".DB_USERSTATS." ORDER BY stat_1 DESC";
$result = mysql_query($sql);
$rows = '';
$data = array();
if (!empty($result))
$rows = mysql_num_rows($result);
else
$rows = '';
if (!empty($rows)){
while ($rows = mysql_fetch_assoc($result)){
$data[] = $rows;
}
}
$rank = 1;
foreach($data as $item){
if ($item['user_id'] == $userid){
return $rank;
}
++$rank;
}
return 1;
}
</code>
I believe there is a way for me to get what i need with something like this but i cant get it to work.
$rankstat1 = getUserRank($userid, 'stat_1'); $rankstat2 =
getUserRank($userid, 'stat_2'); $rankstat3 = getUserRank($userid,
'stat_3');
You can get all the stat ranks using one query without doing all the PHP looping and checking.
I have used PDO in this example because the value of the $userid variable needs to be used in the query, and the deprecated mysql database extension does not support prepared statements, which should be used to reduce the risk of SQL injection.
The function could be adapted to use the same query with mysqli, or even mysql if you must use it.
function getUserRanks($userid, $pdo) {
$sql = "SELECT
COUNT(DISTINCT s1.user_id) + 1 AS stat_1_rank,
COUNT(DISTINCT s2.user_id) + 1 AS stat_2_rank,
COUNT(DISTINCT s3.user_id) + 1 AS stat_3_rank
FROM user_stats f
LEFT JOIN user_stats s1 ON f.stat_1 < s1.stat_1
LEFT JOIN user_stats s2 ON f.stat_2 < s2.stat_2
LEFT JOIN user_stats s3 ON f.stat_3 < s3.stat_3
WHERE f.user_id = ?"
$stmt = $pdo->prepare($sql);
$stmt->bindValue(1, $userid);
$stmt->execute();
$ranks = $stmt->fetchObject();
return $ranks;
}
This should return an object with properties containing the ranks of the given user for each stat. An example of using this function:
$pdo = new PDO($dsn, $user, $pw);
$ranks = getUserRanks(3, $pdo); // get the stat ranks for user 3
echo $ranks->stat_2_rank; // show user 3's rank for stat 2
$sql = "SELECT user_id, stat_1, stat_2, stat_3 FROM ".DB_USERSTATS." ORDER BY stat_1 DESC";
Also, unless there is a reason you need ALL users results, limit your query with a WHERE clause so you're only getting the results you actually need.
Assuming you limit your sql query to just one user, this will get that user's stats.
foreach($data as $item){
$stat_1 = $item['stat_1'];
$stat_2 = $item['stat_2'];
$stat_3 = $item['stat_3'];
}
If you get more than one user's stats with your sql query, consider passing your $data array back to the calling function and loop through the array to match the users stats to particular user id's.

PHP postgresql select, getting id of the one that follows the current one

I am getting 10 rows with the highest ID from a table ...
$result = pg_query($dbconn, "SELECT w_news_id, name, w_newsnachricht, w_newsdatum FROM adempiere.w_news ORDER BY w_news_id DESC LIMIT 10");
... then I build 10 divs in a while loop:
while ($row = pg_fetch_row($result)) {
// building divs here
}
BUT I want to also include the name that belongs to the next w_news_id in that same div (as a "teaser" for the "next"-arrow). So I was thinking I have to run a second query with the ID that would be next in the loop.
How is the SQL syntax for that? Or is there maybe a better way to do this?
You can use the lead window function:
SELECT w_news_id, name, w_newsnachricht, w_newsdatum,
LEAD (name) OVER (ORDER BY w_news_id) AS next_name
FROM adempiere.w_news
ORDER BY w_news_id DESC
LIMIT 10
You can select one more record - LIMIT 11, instead of 10, and process it differently in PHP.
$result = pg_query($dbconn, "SELECT w_news_id, name, w_newsnachricht, w_newsdatum FROM adempiere.w_news ORDER BY w_news_id DESC LIMIT 11");
$i = 0;
while ($row = pg_fetch_row($result) and $i < 10) {
$i++;
// building divs here
}
// then process the arrow and teaser separately (if present)
if ($row = pg_fetch_row($result)) {
// show teaser div
}
UPDATE
The window function solution provided by Mureinik is better.

Retrieve data from MySQL skipping first 4 ouputs where it's ORDER by id

I apologize if the title is confusing, it's hard to title this question.
I've been wondering how I could retrieve data from MySQL but only retrieve data skipping first 4 outputs where it's ordered by id.
Ex:
function firstFour()
{
$sth = $this->db->prepare("SELECT data FROM table WHERE category = 'Sports'
ORDER BY id LIMIT 4");
$sth->execute();
$row = $sth->fetch();
return $row;
}
then on the second query, skip the first four where it's ordered by id on the firstFour query above and output the rest of the data from the sports category.
You need to put limit like follows
LIMIT 4 , 4
LIMIT 8 , 4
so on
Use this query, your limit 4 is making it start from row 0 and retrieve up to row 4, setting the limit as 4, xxxx will go from 4 to whatever xxxx is. I used a large number in place of xxxx
"SELECT data FROM table WHERE category = 'Sports'
ORDER BY id LIMIT 4, 99999999999"
To expand on Zahidul's answer and to make your life easier, you might want to generalize your function a little bit - using firstFour(), secondFour(), etc. is going to make your life a lot harder. I would advise taking Zahidul's idea and passing in your limit variable:
function anyFour($lowLimit)
{
$sth = $this->db->prepare("SELECT data FROM table WHERE category = 'Sports'
ORDER BY id LIMIT $lowLimit, 4");
$sth->execute();
$row = $sth->fetch();
return $row;
}
Then if you wanted to keep the function firstFour(), it would be:
function firstFour()
{
return anyFour(0);
}
From there, you could create a simple loop that incremented by 4.
for ($x = 0; $x < 999;$x++) // 999 should be the total number of sets you want to return...
{
// on each loop, $myRows returns the next 4 rows:
$lowLimit = $x * 4;
$myRows = anyFour($lowLimit);
}
Try this:
$sth = $this->db->prepare("SELECT data FROM table WHERE category = 'Sports'
ORDER BY id;");
$sth->execute();
$row = $sth->fetch();
$row_num = 0;
while ($row) {
$row_num +=1;
if ($row_num > 4) {
//do whatever
}
}

how to check current position in mysql

how can i check current number in mysql where....
my query is
$aid = 16;
$get_prev_photo = mysql_query("SELECT * FROM photos WHERE album_id='$aid' AND pic_id<'$picid' ORDER BY pic_id LIMIT 1");
$get_next_photo = mysql_query("SELECT * FROM photos WHERE album_id='$aid' AND pic_id>'$picid' ORDER BY pic_id LIMIT 1");
while i am getting current photo with following query
$photo = mysql_query("SELECT * FROM photos WHERE pic_id='$picid' LIMIT 1");
and getting total photos in album with following query
$photos = mysql_query("SELECT * FROM photos WHERE album_id='$aid'");
$total_photos = mysql_num_rows($photos);
now i want to check where i am and show it as Showing 1 of 20, showing 6 of 20 and so on...
now i want to check where i am actually...
i think you are referring to pagination, which can be achieved using LIMIT and OFFSET sql
decide the number of results you want per page, then select that many
create links like:
View the next 10
and dynamically change those every time
queries look ~like~
$offset=$_GET['view'];
SELECT * FROM table WHERE `condition`=true LIMIT 5 OFFSET $offset
this translates roughly as
select 5 from the table, starting at the 10th record
This is bad:
$photos = mysql_query("SELECT * FROM photos WHERE album_id='$aid'");
Because it grabs all the fields for the entire album of photos when all you really want is the count. Instead, get the total number of photos in the album like this:
$result = mysql_query("SELECT count(1) as total_photos FROM photos
WHERE album_id='$aid'");
if ($result === false) {
print mysql_error();
exit(1);
}
$row = mysql_fetch_object($result);
$total_photos = $row->total_photos;
mysql_free_result($result);
Now you have the count of the total number of photos in the album so that you can set up paging. Let's say as an example that the limit is set to 20 photos per page. So that means that you can list photos 1 - 20, 21 - 40, etc. Create a $page variable (from user input, default 1) that represents the page number you are on and $limit and $offset variables to plug into your query.
$limit = 20;
$page = $_POST['page'] || 1; // <-- or however you get user input
$offset = $limit * ($page - 1);
I'll leave the part where you code the list of pages up to you. Next query for the photos based on the variables you created.
$result = mysql_query("SELECT * FROM photos WHERE album_id='$aid'
ORDER BY pic_id LIMIT $limit OFFSET $offset");
if ($result === false) {
print mysql_error();
exit(1);
}
$photo_num = $offset;
while ($row = mysql_fetch_object($result)) {
$photo_num++;
$pic_id = $row->pic_id;
// get the rest of the variables and do stuff here
// like print the photo number for example
print "Showing photo $photo_num of $total_photos\n";
}
mysql_free_result($result);
I'll leave better error handing, doing something with the data, and the rest of the details up to you. But that is the basics. Also I did not check my code for errors so there might be some syntax problems above. To make a single photo per page just make $limit = 1.

Categories