Is there a more eloquent way of doing these MySQL queries? - php

I'm making 4 individual queries to a MySQL DB, all of which are identical except the WHERE parameters. 2 of which are:
$totalInvites = mysqli_num_rows(mysqli_query($con, "SELECT code FROM invites"));
$usedInvites = mysqli_num_rows(mysqli_query($con, "SELECT code FROM invites WHERE used IS NOT NULL"));
Is there a way of doing the $totalInvites query and from the returned table, do the WHERE call without doing another query?
If that's confusing, this is an example of what I mean:
$query = mysqli_query($con, "SELECT code FROM invites");
$totalInvites = mysqli_num_rows($query);
$usedInvites = mysqli_num_rows($query /*WHERE used IS NOT NULL*/);
I know that's not proper syntax but that's what I was trying say.

If you just want counts then retrieving the entire database and throwing out the results is not really a good idea. Instead jus task for a count:
SELECT COUNT(*) AS count, used
GROUP BY used
This will give you up to two rows, one count for those that are used and one that isn't presuming used has only NULL or a single non-null value.

Use as little SQL as possible:
SELECT if(used is null, 0, 1) AS used, code
FROM invites
And parse result in PHP according to what you need

SELECT
(SELECT code FROM invites) total
(SELECT code FROM invites WHERE used IS NOT NULL) used

Related

How can i display Mysql entries in a specific order

In my android app i am trying to view a list of friends in the order of who is online and who is not
The code i am using to do it is extracting the request flag (1) from friends table and then use the friend_id to get data from users table and use json_encode to send data back to app in order to display it , the order of friends is displayed in the same order they are in users table :
Here is the code :
if(isset($_POST['list_friends'])) {
$sql = "SELECT friend_id FROM friends WHERE user_id='$user_id' && request='1'";
$res = mysqli_query($connection,$sql) or die(mysqli_error());
$row_to_json = array();
while($rows = mysqli_fetch_assoc($res)) {
foreach($rows AS $row) {
$sql2 = "SELECT * FROM users WHERE id='$row'
ORDER BY FIELD(is_online,'1') DESC";
$res2 = mysqli_query($connection,$sql2) or die(mysqli_error());
while ($rows2 = mysqli_fetch_assoc($res2)) {
//echo $rows_to_json = json_encode((object)$rows2);
$row_to_json[] = (($rows2));
}
}
}
echo json_encode(($row_to_json));
}
is_online field is either (0 if offline and 1 if online)
Any idea of what is wrong in this code ?
EDIT 1 :
I tried this code :
SELECT
friends.friend_id,users.is_online
FROM friends INNER JOIN users ON friends.user_id = users.id
WHERE
(friends.user_id = 21 and request = 1)
ORDER BY
(users.is_online) DESC
I added users.is_online to check for the actual output of this field and this is what is got :
Note that the actual is_online value exists in users table for **22** and
**27** is **0** not **1** !
EDIT 2 :
**
Perfect :)
**
I agree with #Fahad Anjum's comment in that && is very unusual as AND operator in a WHERE condition. Having said this:
1) You could leave away the FIELD() function completely, i.e. write is_online instead of FIELD(is_online, '1').
2) You are using strings where numbers would be sufficient (e.g. user_id = '$user_id' instead of user_id = $user_id). This might be worrying and might cost performance due to implicit casts MySQL might have to do in those cases, and when it comes to the FIELD() function, might be the problem.
The MySQL documentation states:
If all arguments to FIELD() are strings, all arguments are compared as
strings. If all arguments are numbers, they are compared as numbers.
Otherwise, the arguments are compared as double.
In your FIELD() function, you have a mixture of string ('1') and number (is_online) arguments (you have stated that 0 and 1 are possible values of is_online, i.e. is_online contains a number).
I am asking myself what happens when MySQL compares the string '1' with the number 1 after having converted both of them to double, or if something bad happens during the conversion. Theoretically, it should not be a problem because converting a number to double should give the same result as converting that stringified number to double, and because 1 can be represented exactly as a double, but I could imagine that we have a problem here. Unfortunately, I can't test it right now, but you could try writing FIELD(is_online, 1) instead of FIELD(is_online, '1').
3) The main problem is: In your first query, you select friends of the user with the given $user_id. Then you are looping through these friends and for every friend are executing a query against the user table to find out if that user (friend) is online.
That second query returns exactly one row each time; therefore, ordering is useless here.
You will have to solve this problem by doing a join between the friends and the users table in the first place.
Since I have never used PHP, I am a bit reluctant to suggest code here (I don't want to make a fool of myself by publishing code in a language I know nothing about without even being able to test). But your query would resemble the following:
SELECT
friends.friend_id
FROM
(friends INNER JOIN users ON friends.friend_id = users.id)
WHERE
(friends.user_id = $user_id)
ORDER BY
(users.is_online DESC)
Please note that I have left away your second condition here (request = '1') because I can't imagine what it means and it is not that relevant here. You can easily re-add it to the code above.

How to select from mysqli if value from other table equals specific value?

I know I should post a code of what I've tried so far. I really don't know where to start. So at this moment I have 2 working mysqli statements, but I don't know how to combine them.
So, I have two tables.
$sql_ONE = mysqli_query($mysqli, "SELECT * FROM todo WHERE status='open' ORDER BY date ASC LIMIT " . $offset . "," . $items_per_page);
$sql_TWO = mysqli_query($mysqli, "SELECT * FROM permission WHERE memberID=$memberID AND allowed='yes'");
I use $offset and $items_per_page for pagination.
But here it comes: there's a second table that contains a list of members, their memberID and a value (yes/no) wether they may see the row from the first statement or not. So in the first mysqli-statement, all rows are selected where status=open. Before this row's printed on the screen, PHP needs to check if the member who is on the page is allowed to see it. So it should only be shown if allowed=yes.
I don't want them to be in one table, because then I need a row for every single member.
How can I combine those two tables and show them on my screen, still with pagination showing the right amount of rows?
I dont know exactly about your database but by so far understanding I have derived this
SELECT todo.ID
FROM todo
LEFT JOIN permission
ON todo.ID=permission.ID
where permission.allowed='Yes' AND permission.memberID=$memberID
It will join two tables 'todo' and 'perrmission' and will return ID of 'todo' on the basis of condition from permission table.

Php and MySQL Querys using values in other tables

So i'm trying to fetch all of the user_id's from the users-events table where the event_id is equal to the passed in variable (let's say it's 2 for now.)
In the database there are currently 2 ID's registered to that event_id which are 1 and 2.
This code however only returns the first of these values. I feel like i need to incorporate the first query into the while loop but i dont know how to go about it.
Any help would be greatly appriciated!
function showregisteredplayers($id){
$eventq = mysql_fetch_assoc(mysql_query("SELECT user_id FROM `users-events` WHERE event_id = '".$id."'"));
$rosterq = mysql_query("SELECT username FROM `users` WHERE `user_id` = '".$eventq['user_id']."'");
while($player = mysql_fetch_assoc($rosterq)){
echo("
<tr>
<td>".$player['username']."</td>
</tr>
");
}
}
Use a sub query then kill your first one.
SELECT username FROM `users` WHERE `user_id` IN
(
SELECT user_id FROM `users-events` WHERE event_id = 5
)
Rest is fine, you already are looping over the second result set so this should do. Unless you have a large number of records, there should not be any considerable performance degradation with the use of IN otherwise you can optimize the query.
5 is obviously just an example, use $id there correctly.
Why not use a JOIN?
SELECT username
FROM `users` AS u
INNER JOIN `users-events` AS ue ON u.user_id = ue.user_id
WHERE event_id = ?
Several advices:
Don't use mysql_ functions because are deprecated
Use prepared queries, then you only need to loop through execute method, take a look to Example 3 in this link (example from php.net using mysqli)

Addition from MySQL query

I am trying to add this:
if (question_counter==10){
$query3 = "SELECT answer_points WHERE participation_id=".$participation_id;
$dbc->query($query3)
}
This is supposed to get all the answer_points where the participation_id = "something". This happens when I receive in my PHP function that question_counter has reached 10
I now want to perform an addition between all the results I receive in my query above so that I can find out a total score and store it as a variable.
How would I go about doing this efficiently?
I thought about writing queries for each answer where I get the participation_id and the question_counter to write the query, store each row result in a separate variable and add all those together. I think this is an overkill and dumb since I will have to write 10 queries to get each row's result.
Anyway this is my Table
You can use MySQL's SUM function.
SELECT SUM(columnName) AS totalScore FROM tableName WHERE id = 34;
Your query is not correct.
$query3 = "SELECT answer_points FROM table_name WHERE participation_id=".$participation_id;
^^^^^^^^^^^^^^^
from and table name
You have forgot from and table name in the query.
To get the sum of the column you need to use the SUM function of mysql.
Here is tutorial of SUM function in mysql.
You have to write query using SUM function
$query3 = "SELECT SUM(answer_points) AS answer_points
FROM TABLE_NAME
WHERE participation_id=".$participation_id;

Problems with querying when a value is null

I am using php to query a database for one piece of information from each of 10 separate tables currently. The problem with using multiple queries is that it is extremely slow when accessing the web page that uses all of this information. I cannot seem to get all of the information back that I am wanting when one of the values does not exist due to the WHERE... statement.
For instance, my single queries are all in this format:
SELECT eval_id FROM eval WHERE user_id = $id;
My multiple table query looks like this:
SELECT eval_id,list_id,tab_id
FROM eval,list,tab
WHERE eval.user_id = $id
AND list.user_id = $id
AND tab.user_id = $id;
I tried to combine these queries into one large query, but when the user_id of one does not exist in the table, the comparison in the WHERE... statement screws up the entire query. Does anyone know the best way to retrieve all of this information?
Assume that the tables are "eval, list, and tab," and their id's are *_id respectively. What would be the best way to query this even if eval does not contain a result where the user_id = $id?
SELECT eval.eval_id, list.list_id
FROM user
JOIN eval ON eval.user_id = user.id
JOIN list ON list.user_id = user.id
WHERE user.id = $id
Hope it can help you.
Update: Just think about other solution:
SELECT eval_id as id, "eval" as table
FROM eval WHERE eval.user_id = $id
UNION
SELECT list_id as id, "list" as table
FROM list WHERE list.user_id = $id
You could use either of the following to your query in the WHERE statement:
AND TABLE.TABLE_id <> null //null
AND TABLE.TABLE_id <> 'null' //String null
AND TABLE.TABLE_id <> '' //empty String
Check your database to see what kind of empty value your id is returning and choose the addition that matches it.
Also, while LEFT JOINs may be better looking in a query, they are not always faster so make sure you test it before using.

Categories