Is there any better way to do sorting option? - php

So, I'm trying to make option that will sort results from database. I found a way to do this, but I'm not sure it's best.
if(!isset($_GET['sort']) || $_GET['sort'] == 0) {
$userquery = $DBH->query("SELECT users.id, users.username, users.name, users.joined, users.usergroup, user_groups.group_title FROM users INNER JOIN user_groups ON users.usergroup = user_groups.id ORDER BY users.id ASC");
$userquery->setFetchMode(PDO::FETCH_OBJ);
} else {
if($_GET['sort'] == 1) {
$userquery = $DBH->query("SELECT users.id, users.username, users.name, users.joined, users.usergroup, user_groups.group_title FROM users INNER JOIN user_groups ON users.usergroup = user_groups.id ORDER BY users.username ASC");
$userquery->setFetchMode(PDO::FETCH_OBJ);
} else if($_GET['sort'] == 2) {
$userquery = $DBH->query("SELECT users.id, users.username, users.name, users.joined, users.usergroup, user_groups.group_title FROM users INNER JOIN user_groups ON users.usergroup = user_groups.id ORDER BY users.name ASC");
$userquery->setFetchMode(PDO::FETCH_OBJ);
} else if($_GET['sort'] == 3) {
$userquery = $DBH->query("SELECT users.id, users.username, users.name, users.joined, users.usergroup, user_groups.group_title FROM users INNER JOIN user_groups ON users.usergroup = user_groups.id ORDER BY user_groups.group_name ASC");
$userquery->setFetchMode(PDO::FETCH_OBJ);
}
}
Is there any better way to do this?

There's no need to repeat the non-changing parts of the query over and over again. Just put that into a variable and append the ORDER BY clause to that string depending on the condition. Then use the string as the query parameter.
$querystring = "SELECT users.id, users.username, users.name, users.joined, users.usergroup, user_groups.group_title FROM users INNER JOIN user_groups ON users.usergroup = user_groups.id ORDER BY ";
switch($_GET['sort']) {
case 1:
$querystring.= "users.username ASC";
break;
case 2:
$querystring.= "users.name ASC";
break;
case 3:
$querystring.= "user_groups.group_name ASC";
break;
case 0:
default:
$querystring.= "users.id ASC";
break;
}
$userquery = $DBH->query($querystring);
$userquery->setFetchMode(PDO::FETCH_OBJ);

Related

SQL JOIN does not return any results

if(isset($_GET['id']) && $_GET['id'] != null) {
$id = $_GET['id'];
$sql = "SELECT
`maps.name`,
`maps.description`,
`maps.date`,
`maps.mcversion`,
`maps.mapid`,
`maps.category`,
`maps.format`,
`users.username`,
`users.rank`,
`users.verified`,
`users.mcusername`,
COUNT(`views.mapid`) AS `views`,
COUNT(`likes.mapid`) AS `likes`,
COUNT(`downloads.mapid`) AS `downloads`,
COUNT(`subscribes.channelid`) AS `subscribers`
FROM `maps` INNER JOIN `users` ON `maps.userid` = `users.id`
INNER JOIN `views` ON `maps.mapid` = `views.mapid`
INNER JOIN `likes` ON `maps.mapid` = `likes.mapid`
INNER JOIN `downloads` ON `maps.mapid` = `downloads.mapid`
INNER JOIN `subscribe` ON `mapid.userid` = `subscribe.channelid`
WHERE `maps.mapid` = '$id'";
$result = mysqli_query($con,$sql);
if (mysqli_num_rows($result) > 0) {
echo “success”;
} else {
header("LOCATION: index.php");
}
$sql = "SELECT * FROM `maps` WHERE `id`=$id";
$result = mysqli_query($con,$sql);
if (mysqli_num_rows($result) > 0) {
viewer($id);
} else {
header("LOCATION: index.php");
}
This worked, but I need data from more tables.
$sql = "SELECT
`maps.name`,
`maps.description`,
`maps.date`,
`maps.mcversion`,
`maps.mapid`,
`maps.category`,
`maps.format`,
`users.username`,
`users.rank`,
`users.verified`,
`users.mcusername`,
COUNT(`views.mapid`) AS `views`,
COUNT(`likes.mapid`) AS `likes`,
COUNT(`downloads.mapid`) AS `downloads`,
COUNT(`subscribes.channelid`) AS `subscribers`
FROM `maps`
INNER JOIN `users` ON `maps.userid` = `users.id`
INNER JOIN `views` ON `maps.mapid` = `views.mapid`
INNER JOIN `likes` ON `maps.mapid` = `likes.mapid`
INNER JOIN `downloads` ON `maps.mapid` = `downloads.mapid`
INNER JOIN `subscribe` ON `mapid.userid` = `subscribe.channelid`
WHERE `maps.mapid` = '$id'";
Is this sql join good? Why it does not return any results?
with the normal $sql = "SELECT * FROM maps WHERE id=$id"; everything works, but i need data from the other tables too.
The solution:
$sql = "SELECT
maps.name,
maps.description,
maps.date,
maps.mcversion,
maps.mapid,
maps.category,
maps.format,
users.username,
users.rank,
users.verified,
users.mc_username,
(SELECT COUNT(*) FROM likes WHERE likes.mapid = maps.id) AS likes,
(SELECT COUNT(*) FROM downloads WHERE downloads.mapid = maps.id) AS downloads,
(SELECT COUNT(*) FROM subscribe WHERE subscribe.channelid = maps.userid) AS subscribers,
(SELECT COUNT(*) FROM views WHERE views.mapid = maps.id) AS viewers
FROM maps
INNER JOIN users
ON maps.userid = users.id
WHERE maps.id = '$id'";
Thanks for the help!
IF you would like to secure a complex sql statment, how would you do it?
Is it an ok version?:
if(isset($_GET['id']) && $_GET['id'] != null) {
$id = $_GET['id'];
$stmt = $mysqli->prepare('SELECT id FROM maps WHERE id = ?');
$stmt->bind_param('i', $id);
$stmt->execute();
$result = $stmt->get_result();
if (mysqli_num_rows($result) == 1) {
$row = $result->fetch_assoc();
$secid = $row["id"];
} else {
echo "error2";
}
$sql = "SELECT
maps.name,
maps.description,
maps.date,
maps.mcversion,
maps.mapid,
maps.category,
maps.format,
users.username,
users.rank,
users.verified,
users.mc_username,
(SELECT COUNT(*) FROM likes WHERE likes.mapid = maps.id) AS likes,
(SELECT COUNT(*) FROM downloads WHERE downloads.mapid = maps.id) AS downloads,
(SELECT COUNT(*) FROM subscribe WHERE subscribe.channelid = maps.userid) AS subscribers,
(SELECT COUNT(*) FROM views WHERE views.mapid = maps.id) AS viewers
FROM maps
INNER JOIN users
ON maps.userid = users.id
WHERE maps.id = '$secid'";
$result = mysqli_query($con,$sql);
if (mysqli_num_rows($result) > 0) {
$row = mysqli_fetch_assoc($result);
echo $row["name"];
} else {
echo "error3";
}
} else {
echo "error1";
}
database connection:
$mysqli = new mysqli('127.0.0.1', 'root', 'pass’, 'db’);

AND NOT is not working sql query in php

I don't want data where value =comedy and value=english
but this query is showing data where value is english
else if(($_POST['genre'] == "Action")&&($_POST['language'] == "Hindi")) {
$query = "SELECT movies.Title,movies.Description,movies.Movie_length,movies.Movie_release_date,movies.Featured_image
FROM((relationship INNER JOIN category ON relationship.Category_id=category.Id)
INNER JOIN movies ON relationship.Movies_id=movies.Id)
WHERE NOT category.value='Comedy' AND NOT category.value='English'";
$search_result = filterTable($query);
try this:
else if(($_POST['genre'] == "Action")&&($_POST['language'] == "Hindi")) {
$query = "SELECT movies.Title,movies.Description,movies.Movie_length,movies.Movie_release_date,movies.Featured_image
FROM((relationship INNER JOIN category ON relationship.Category_id=category.Id)
INNER JOIN movies ON relationship.Movies_id=movies.Id)
WHERE category.value NOT LIKE 'Comedy' AND category.value NOT LIKE 'English'";
$search_result = filterTable($query);
or:
else if(($_POST['genre'] == "Action")&&($_POST['language'] == "Hindi")) {
$query = "SELECT movies.Title,movies.Description,movies.Movie_length,movies.Movie_release_date,movies.Featured_image
FROM((relationship INNER JOIN category ON relationship.Category_id=category.Id)
INNER JOIN movies ON relationship.Movies_id=movies.Id)
WHERE category.value NOT IN ('Comedy','English')";
$search_result = filterTable($query);

Using php if...else statement with two queries

I have two queries that count the number of data for both "artists" and "groups" in my database. I want to display a message if there is data to display for either artists or groups (or both), and if the data returns 0 for both of them then not to display anything.
I have the following code which doesn't seem to work:
<?php if (($numrowsartists==0)OR($numrowsgroups==0)) {
} else {
echo "There is information to display.";
}
?>
Below are the queries I have:
$query = "SELECT COUNT(*) FROM `Credit_To_Artist` AS c2a
INNER JOIN `Credits` AS cr ON cr.credit_id = c2a.credit_id
INNER JOIN `Artist` AS a ON a.artist_id = c2a.artist_id
WHERE c2a.song_id = $id";
$res = mysql_query($query);
$numrowsartists = mysql_fetch_assoc($res);
$query = "SELECT COUNT(*) FROM `Credit_To_Artist` AS c2a
INNER JOIN `Credits` AS cr ON cr.credit_id = c2a.credit_id
INNER JOIN `Artist_Group` AS ag ON ag.group_id = c2a.group_id
WHERE c2a.song_id = $id
ORDER BY ag.group_name ASC";
$res = mysql_query($query);
$numrowsgroups = mysql_fetch_assoc($res);
Thanks in advance. I'm sure it's probably a super basic fix but I'm still very new to php and would appreciate some help.
You should getthe value frorm the row eg using alias for column name
$query = "SELECT COUNT(*) as num_artists FROM `Credit_To_Artist` AS c2a
INNER JOIN `Credits` AS cr ON cr.credit_id = c2a.credit_id
INNER JOIN `Artist` AS a ON a.artist_id = c2a.artist_id
WHERE c2a.song_id = $id";
$res = mysql_query($query);
$row = mysql_fetch_assoc($res);
$numrowsartists = row['num_artists'];
$query = "SELECT COUNT(*) as num_groups FROM `Credit_To_Artist` AS c2a
INNER JOIN `Credits` AS cr ON cr.credit_id = c2a.credit_id
INNER JOIN `Artist_Group` AS ag ON ag.group_id = c2a.group_id
WHERE c2a.song_id = $id
ORDER BY ag.group_name ASC";
$res = mysql_query($query);
$row = mysql_fetch_assoc($res);
$numrowsgroups = row['num_groups'];
There are several solutions, the easiest being the following:
if($numrowsartists[0]+$numrowsgroups[0] > 0)
However, as people have said, you shouldn't use mysql_* functions anymore.
Assuming the ID is user input, you should really use prepared statements.
Also, you can handle both tests in a single query:
$stmt = $con->mysqli_prepare("SELECT COUNT(1) as `count` FROM `Credit_To_Artist` AS c2a
INNER JOIN `Credits` AS cr ON cr.credit_id = c2a.credit_id
INNER JOIN `Artist` AS a ON a.artist_id = c2a.artist_id
INNER JOIN `Artist_Group` AS ag ON ag.group_id = c2a.group_id
WHERE c2a.song_id = ?");
$stmt->bind_param('i',$id);
$stmt->execute();
if($stmt->get_result()->fetch_array()[0] > 0){
...
}else{
//message that nothing was found
}

MySQLi prepared statement within while loop

I'm attempting to execute 4 prepared statement within a mysqli_fetch_row while loop. Currently my code is outputting NULL or empty values for all queries. This is my first time using prepared statements and I am trying to convert my code from mysql queries to mysqli. My code is below:
$users = mysqli_query($link, "SELECT id FROM users WHERE approved = '1'");
while ($user = mysqli_fetch_row($users)) {
if ($twitter_username_query = mysqli_prepare($username_query, "SELECT username FROM personas WHERE user_id = ?")) {
mysqli_stmt_bind_param($username_query, "d", $user[0]);
mysqli_stmt_execute($username_query);
mysqli_stmt_bind_result($username_query, $username);
mysqli_stmt_fetch($username_query);
mysqli_stmt_close($twitter_username_query);
}
if ($count_user_clicks = mysqli_prepare($count_user_clicks, "SELECT count(distinct txid) FROM users_clicks WHERE user_id = ?")) {
mysqli_stmt_bind_param($count_user_clicks, "d", $user[0]);
mysqli_stmt_execute($count_user_clicks);
mysqli_stmt_bind_result($count_user_clicks, $user_clicks);
mysqli_stmt_fetch($count_user_clicks);
mysqli_stmt_close($count_user_clicks);
}
if ($count_user_installs = mysqli_prepare("SELECT count(txid) FROM (SELECT txid FROM users_installs WHERE user_id = ? GROUP BY txid) table1")) {
mysqli_stmt_bind_param($count_user_installs, "d", $user[0]);
mysqli_stmt_execute($count_user_installs);
mysqli_stmt_bind_result($count_user_installs, $user_installs);
mysqli_stmt_fetch($count_user_installs);
mysqli_stmt_close($count_user_installs);
}
if ($calc_user_cost = mysqli_prepare($calc_user_cost, "SELECT sum(earnings) FROM (SELECT max(cost) as earnings FROM users_clicks WHERE user_id = ? GROUP BY txid) table1")) {
mysqli_stmt_bind_param($calc_user_cost, "d", $user[0]);
mysqli_stmt_execute($calc_user_cost);
mysqli_stmt_bind_result($calc_user_cost, $user_cost);
mysqli_stmt_fetch($calc_user_cost);
mysqli_stmt_close($calc_user_cost);
}
if ($user_clicks == '0') {
$user_conv = 0;
} else {
$user_conv = ($user_installs / $user_clicks) * 100;
}
echo "<tr>";
echo "<td><b>".$username."</b></td>";
echo "<td>".number_format($user_clicks)."</td>";
echo "<td>".number_format($user_installs)."</td>";
if ($user_installs[0] == '0') {
echo "<td>$0.00</td>";
} else {
echo "<td>$".number_format($user_cost / $user_installs, 2)."</td>";
}
echo "<td>".number_format($user_conv, 2)."%</td>";
echo "</tr>";
}
Use a single query that JOINs all the subqueries:
SELECT u.id, p.username, IFNULL(c.clicks, 0) AS clicks, IFNULL(i.installs, 0) AS installs, IFNULL(e.earnings, 0) AS earnings
FROM users AS u
JOIN personas AS p ON p.user_id = u.id
LEFT JOIN (
SELECT user_id, COUNT(DISTINCT txid) AS clicks
FROM user_clicks
GROUP BY user_id) AS c ON c.user_id = u.id
LEFT JOIN (
SELECT user_id, COUNT(DISTINCT txid) AS installs
FROM user_installs
GROUP BY user_id) AS i ON i.user_id = u.id
LEFT JOIN (
SELECT user_id, SUM(earnings) AS earnings
FROM (SELECT user_id, txid, MAX(cost) AS earnings
FROM user_clicks
GROUP BY use_id, txid) AS table1
GROUP BY user_id) AS e
WHERE u.approved = 1

MYSQLI SELECT with Limit not working

I'm trying to find the number of rows in a table in the database depending on certain conditions with a limit feature so that i can count the number of rows there are matching the condition after a certain row in the table.
Thus i created my php query:
$q = $db->query("SELECT u.*, f.* FROM updates U LEFT JOIN friends f ON f.fid = u.userid WHERE f.uid = '$userid' ORDER BY u.up_id DESC LIMIT $limitID, 9999999");
$nr = $q->num_rows;
However even if there are more rows in the database after the $limitID, it says there are no rows.
If I try this:
$q = $db->query("SELECT u.*, f.* FROM updates U LEFT JOIN friends f ON f.fid = u.userid WHERE f.uid = '$userid' ORDER BY u.up_id DESC LIMIT $limitID");
$nr = $q->num_rows;
then it works, but it doesnt count after the $limitID. Any udeas?
According yo your query, it should be like
$sql = "SELECT count(*) FROM updates U
LEFT JOIN friends f ON f.fid = u.userid WHERE f.uid = ?";
// getting stuff using prepared statements
$row = $res->fetch_row();
$num = $row[0] - $limitID;
but I doubt it's really what you need either.
Using what Your Common Sense told me I managed to find an answer to my problem, so here it is:
$limitID = $upid;
$sql = "SELECT count(*) FROM updates u
LEFT JOIN friends f ON f.fid = u.userid WHERE
(f.uid = '$userid' AND u.up_id > '$limitID')";
$res = $db->query($sql);
$row = $res->fetch_row();
$num = $row[0];
if($num == 0){
// do nothing
} else {
echo "<span class='newPosts'>" .$num. " New Post"
. (($num>1)?'s':' ') . "</span>";
}
works perfectly

Categories