images pagination - how to get all params in one single query - php

I have a pagination system for viewing images from database.
So each time I click on a next / prev buttons I need three variables
Question - is there a way to get them in one single query and not using a separate query for each of them?
$lm = 100; // limit per page
$off = 0; // offset - click on next prev buttons
$dim = '960 x 540'; // img dimensions
function get_images($lm, $off, $dim){
global $db;
//firstly I need total number of images
$st = $db->query("select count(*) as cnt from images");
$total = $st->fetchColumn();
//then I need number of 960 x 540 images
$st = $db->query("select * from images where dim = '" . $dim . "'");
$insel = $st->rowCount();
//then I need number of viewed images on a pagination system
$st = $db->query("select * from images where dim = '" . $dim . "' order by date desc limit " . $lm . "
offset " . $off);
$inview = $st->rowCount();

$st = $db->query("select * from images where dim = '" . $dim . "' count(id) over(partition by id) as cnt count(dim) over(partition by dim) as insel order by date desc limit " . $lm . " offset " . $off);
But make sure you are using MySQL version greater than or equal to 8.0

Related

Why doesnt this update update the score?

I am trying to create an update that whenever the user gets an offer lower than the last day/week average price they get points for it 50 for last day and 20 for last week
I am desperate I have been trying for the longest time to chage thing on the proyect and now when I try to update that for every time the condition is met to update the db, it does its work and see when the price is cheaper and where it isnt but never increases the score which bugs me a lot¿can someone help?
function check_if_offer_cheaper_with_twenty_than_previous_day($prodname, $price)
// Check if the price found by the user is 20% lower than the most recent available average price of the previous day
{
global $db;
$sql = 'SELECT AVG(prices.price) >"' . $price / 0.8 . '" AS cheaper_than_previous_day'
. " FROM prices"
. ' WHERE prices.prodname = "' . $prodname . '"' .
' AND prices.date = CURDATE() - INTERVAL 1 DAY';
$result = mysqli_query($db, $sql);
$row = mysqli_fetch_assoc($result);
if (isset($row['cheaper_than_previous_day'])) {
$query = "UPDATE users SET total_score = total_score +50,
score_this_month = score_this_month + 50 WHERE id = '" . $_SESSION['user']['id'] . "'";
mysqli_query($db, $query);
return $row['cheaper_than_previous_day'];
} else {
return true;
}
}
function check_if_offer_cheaper_with_twenty_than_previous_week($prodname, $price)
// Check if the price found by the user is 20% lower than the most recent average price available in the previous week
{
global $db;
$sql = 'SELECT AVG(prices.price) > "' . $price / 0.8 . '" AS cheaper_than_previous_week'
. " FROM prices"
. ' WHERE prices.prodname = "' . $prodname .
'" AND prices.date BETWEEN CURDATE() - INTERVAL 8 DAY AND CURDATE() - INTERVAL 1 DAY';
$result = mysqli_query($db, $sql);
$row = mysqli_fetch_assoc($result);
if (isset($row['cheaper_than_previous_week'])) {
$query = "UPDATE users SET total_score = total_score +20, score_this_month = score_this_month +50
WHERE id = '" . $_SESSION['user']['id'] . "'";
mysqli_query($db, $query);
return $row['cheaper_than_previous_week'];
} else {
return true;
}
}
MySQL syntax uses commas to separate the assignment pairs, like this
$query = "UPDATE users SET total_score = total_score +20,
score_this_month = score_this_month +50
WHERE id = '" . $_SESSION['user']['id'] . "'";
dev.mysql 8.0 update syntax
That is assuming that $_SESSION['user']['id'] does not evaluate to null.

Pull values from a row based on ID

Hoping someone can shed light on this. I am trying to pull the value from 2 fields from a row and based on the row being expired, exclude those 2 values from a drop down list.
I have a table (schedule)
gameID
homeID
visitorID
gameTimeEastern
weekNum
each week there are matchups where 2 teams play each other. Those 2 teams are in a row based on gameID with a specific start time (gameTimeEastern).
I have a function that determines when the matchup is locked, meaning the game has started:
function gameIsLocked($gameID) {
//find out if a game is locked
global $mysqli, $cutoffDateTime;
$sql = "select (DATE_ADD(NOW(), INTERVAL " . SERVER_TIMEZONE_OFFSET . " HOUR) > gameTimeEastern or DATE_ADD(NOW(), INTERVAL " . SERVER_TIMEZONE_OFFSET . " HOUR) > '" . $cutoffDateTime . "') as expired from " . DB_PREFIX . "schedule where gameID = " . $gameID;
$query = $mysqli->query($sql);
if ($query->num_rows > 0) {
$row = $query->fetch_assoc();
return $row['expired'];
}
$query->free;
die('Error getting game locked status: ' . $mysqli->error);
This basically determines if the row is expired (gameTimeEastern has passed). I then have a drop down on a form that has a list of all the teams from each matchup for that week.If the row is expired, then I do not want to include the homeID or visitorID from that row in the drop down.
On my page I am trying to show those teams from the expired row but it is failing as the page stops processing when it hit this:
//get expired teams
$expiredGames =gameIsLocked(gameID);
// echo 'Expired games are GAME ' . $expiredGames . '<br>';
for ($eti=1; $eti<=$gameID; $eti++)
{
if ($gameID[$eti]>''){
$sql = "select * from " . DB_PREFIX . "schedule WHERE gameID = '" . $gameID[$eti] . "';";
$query = $mysqli->query($sql);
if ($query->num_rows > 0) {
$result = $query->fetch_assoc();
$expiredHomeTeam = $result['homeID'];
$expiredVisitorTeam = $result['visitorID'];
}
}
echo 'Expired teams for GAME '.$gameID.' are '.$expiredHomeTeam.' and '.$expiredVisitorTeam.'<br>';
}
NEW CODE - Actually giving me the first result
//get expired teams
$expiredGames =gameIsLocked(gameID);
$sql = "select * from " . DB_PREFIX . "schedule WHERE weekNum = '6';";
$query = $mysqli->query($sql);
if ($query->num_rows > 0) {
$result = $query->fetch_assoc();
$expiredHomeTeam = $result['homeID'];
$expiredVisitorTeam = $result['visitorID'];
}
echo 'Expired teams for GAME ' . $expiredGames . ' are '.$expiredHomeTeam.' and '.$expiredVisitorTeam.'<br>';
Ended up using the SQL query to schedule to get results I needed. Thanks for the direction. The logic was already there, just needed to add an if statement to how I populated the array for teams in the drop down.

Selecting data of a 'person'' using LIMIT from table

I was wondering how to fetch data of a person from a table. I found the query to LIMIT data fetch from table. Here is what I got so far:
$result = mysql_query("SELECT * FROM users WHERE username = '" . $username[$x] . "' LIMIT " . $last_limt . " , " . $nxt_limt . "");
It returns data when LIMIT is available but if the LIMIT exceed the entire data returns null. So how can I know if ROW is available or not in table?
use mysql Count
SELECT count(username) FROM users WHERE username ='xyz'
And your $last_limt is not grater than total count-1
You have to check number of rows of the result from that query before proceeding
$result = mysql_query("SELECT * FROM users WHERE username = '" . $username[$x] . "' LIMIT " . $last_limt . " , " . $nxt_limt . "");
$rowcount=mysql_num_rows($result);
if($rowcount > 0)
{
//next operations
}
else
{
//No more data
}

Try to separate a loop result

I'm making a poll, and I have a php script to get the percents of the number voted for that poll option. When i run a query I just keep getting 0 for the options. How can I make it so that each $val1 has a different number according to the row total in the database for?
For example: poll option 1 has 1 vote, poll option 2 has 1 vote, poll option 3 has 0 and poll option 4 has 0. and the query would output 50 option one and option 2 and 0 for option 3 and four.
My code
$poll = $db->fetch("SELECT * FROM home_poll ORDER BY id DESC LIMIT 1");
$option_sql = $db->query("SELECT total FROM home_polls_option WHERE poll_id = '" . $poll['id'] . "'");
while ($row = mysqli_fetch_array($option_sql)) {
$val1 = $row['total'];
}
$poll_votess = $db->query("SELECT * FROM home_polls_vote WHERE poll_id = '" . $poll['id'] ."'");
$val2 = $poll_votess->num_rows;
$res = round ($val1 / $val2 * 100);
$options1 .= ' <script>
var doughnutData = [
{
value: ' . $res . ',
color:"#F7464A"
},
{
value : ' . $res . ',
color : "#46BFBD"
},
{
value : ' . $res . ',
color : "#FDB45C"
},
{
value : '. $res.',
color : "#949FB1"
}
];
var myDoughnut = new Chart(document.getElementById("canvas").getContext("2d")).Doughnut(doughnutData);
</script>';
Database :
home_polls_vote: http://prntscr.com/2vd1lt
home_polls_option: http://prntscr.com/2vd1k7
In while loop you have took in $val1 just latest row value and because it is 0 votes, you got everywhere 0. You need to put it into array and later on use $res as array also so you can print different values down there in your script.
EDIT:
You can try something like this. First fetch total number of votes, then put percent in result in while loop.
$poll = $db->fetch("SELECT * FROM home_poll ORDER BY id DESC LIMIT 1");
$option_sql = $db->query("SELECT total FROM home_polls_option WHERE poll_id = '" . $poll['id'] . "'");
$poll_votess = $db->query("SELECT * FROM home_polls_vote WHERE poll_id = '" . $poll['id'] ."'");
$number_of_votes= $poll_votess->num_rows;
while ($row = mysqli_fetch_array($option_sql)) {
$res[] = round ($row['total'] / $number_of_votes * 100);
}
$options1 .= '<script>
var doughnutData = [
{
value: ' . $res[0] . ',
color:"#F7464A"
},
{
value : ' . $res[1] . ',
color : "#46BFBD"
},
{
value : ' . $res[2] . ',
color : "#FDB45C"
},
{
value : '. $res[3].',
color : "#949FB1"
}
];
var myDoughnut = new Chart(document.getElementById("canvas").getContext("2d")).Doughnut(doughnutData);
</script>';
Use mysql it'self for calculation this will avoid many lines of code and ease to process
http://dev.mysql.com/doc/refman/5.0/en/precision-math-rounding.html
https://dev.mysql.com/doc/refman/5.0/en/case.html
$sql = " SELECT ROUND(COUNT(hpv.id)/hpo.total * 100) AS res
FROM home_polls_option AS hpo
JOIN home_polls_vote AS hpv ON hpv.poll_id = hpo.poll_id
WHERE hpv.poll_id=$poll ['id']
GROUP BY hpo.value";

How to control last visitor ip through sql and php?

I am trying to make a unique visitors counter for my pages using mysql and php. Im my DB table i have a "views" column and a "last_ip" column.
If the ip of the current user is equal to the last ip stored on DB the counter dies, if the current user ip is different from the last ip stored on DB the current user ip is stored as last ip on DB and the counter sums +1 to the views on DB.
The main idea is:
1 - check the ip of the current user and save it to variable $viewer_ip
2 - check the last ip stored on DB and save it to variable $last_viewer_ip
3 - compare those 2 variables, if $viewer_ip =! $last_viewer_ip the function should store $last_viewer_ip in "last_ip" field and sums +1 in "views" field. Else it should do nothing.
<?php
$viewer_ip = $user_ip = $h->cage->server->testIp('REMOTE_ADDR');
$sql = "SELECT post_last_viewer_ip FROM " . TABLE_POSTS . " WHERE post_id = %d";
$last_viewer_ip = $h->db->get_var($h->db->prepare($sql, $h->post->id));
if ($viewer_ip AND $viewer_ip != $last_viewer_ip) {
$sql = "UPDATE " . TABLE_POSTS . " SET post_last_viewer_ip = '" . $viewer_ip . "' WHERE post_id = %d";
$h->db->query($h->db->prepare($sql, $h->post->id));
}
if ($viewer_ip != $last_viewer_ip) {
$sql = "UPDATE " . TABLE_POSTS . " SET post_views = post_views + 1 WHERE post_id = %d";
$h->db->query($h->db->prepare($sql, $h->post->id));
}
?>
that code works in parts, cause it sums like 3 views, on each visit, as u can see, that code is a trash, cause i did it myself and i am no expert.
Anyone can try a fix on this? ty.
You need to store the session id of your visitors to the database to be able to do that kind of thing correctly. A unique visitor is considered one that is there for one specific session. If the user closes the browser and comes back, then it is another visitor.
If you want truly unique visitors, you need to store cookies too and use them to identify your visitors, but then again, cookie blocked? Cookie flushed? You're screwed...
Last method is to force a login, with a login you usually have a user_id, that user_id becomes your unicity.
I'll let you decide how you want to handle your unicity...
For the storage part, you need at least 1 table where you store the requests and identity of your requesters. Store in that table the following information:
Page/SpecificRequest
UserIP/SessionID/CookieID/UserId
RequestDate
RequestTime
Then on each page request, store a request in that table such as:
INSERT INTO myrequests VALUES(
$_REQUEST['URI'],
session_id(),
date('Y-m-d'),
date('G:i:s')
)
And then, to retrieve the unique visitor count, you just group on the data:
SELECT RequestDate, COUNT(*) AS uniquevisitors
FROM myrequests
GROUP BY RequestDate, session_id()
Good luck
Try it this way..
You need one separate table (TABLE_WITH_LOGS) for IP logs, which has 3 columns post_viewer_ip varchar(15), timestamp timestamp, post_id bigint (or whatever type you have for you post ids).
The code will look something like that one..
$timeout = 30*60; // count as a new visit after 30 minutes
$viewer_ip = $user_ip = $h->cage->server->testIp('REMOTE_ADDR');
// check if there is a record within the timeout period
$sql = "SELECT count(*) FROM " . TABLE_WITH_LOGS . " WHERE post_id = %d
AND ip = '%s' AND `timestamp` > NOW() - $timeout";
$rows = $h->db->get_var($h->db->prepare($sql, $h->post->id, $viewer_ip));
if ($rows == 0) { // no recent records in DB, insert new one
$sql = "INSERT INTO " . TABLE_WITH_LOGS . " SET post_viewer_ip = '" .
$viewer_ip . "', `timestamp` = NOW() WHERE post_id = %d";
$h->db->query($h->db->prepare($sql, $h->post->id));
// update counter
$sql = "UPDATE " . TABLE_POSTS . " SET post_views = post_views + 1
WHERE post_id = %d";
$h->db->query($h->db->prepare($sql, $h->post->id));
}
else { // there is at least one record, update it with current timestamp
$sql = "UPDATE " . TABLE_WITH_LOGS . " SET `timestamp` = NOW()
WHERE post_id = %d and post_viewer_ip = '$viewer_ip' LIMIT 1";
$h->db->query($h->db->prepare($sql, $h->post->id));
}
// cleanup table from time to time
if (rand(1,5)<2) {
$sql = "DELETE " . TABLE_WITH_LOGS . " WHERE `timestamp` < NOW() - $timeout";
$h->db->query($sql);
}
ps: you may skip part with timestamp update and always insert a new record. It will make less (only by one :)) SQL requests.
$timeout = 30*60; // count as a new visit after 30 minutes
$viewer_ip = $user_ip = $h->cage->server->testIp('REMOTE_ADDR');
// check if there is a record within the timeout period
$sql = "SELECT count(*) FROM " . TABLE_WITH_LOGS . " WHERE post_id = %d
AND ip = '%s' AND `timestamp` > NOW() - $timeout";
$rows = $h->db->get_var($h->db->prepare($sql, $h->post->id, $viewer_ip));
if ($rows == 0) { // no recent records in DB, update counter
$sql = "UPDATE " . TABLE_POSTS . " SET post_views = post_views + 1
WHERE post_id = %d";
$h->db->query($h->db->prepare($sql, $h->post->id));
}
// record last visit
$sql = "INSERT INTO " . TABLE_WITH_LOGS . " SET post_viewer_ip = '" .
$viewer_ip . "', `timestamp` = NOW() WHERE post_id = %d";
$h->db->query($h->db->prepare($sql, $h->post->id));
// cleanup table from time to time
if (rand(1,5)<2) {
$sql = "DELETE " . TABLE_WITH_LOGS . " WHERE `timestamp` < NOW() - $timeout";
$h->db->query($sql);
}

Categories