MySQL SELECT COUNT with if statement - What is the best practice? - php

I'm getting inconsistent results with the way I'm doing this so I thought I'd ask the geniuses here what you think. Here is what I'm doing...
$ccquerycount = "SELECT COUNT(*) as `count` FROM payments_cc_info WHERE user_id=$userid";
....
....
if ($row['count'] == "1") {
} else {
}
Is there a better way to design the if statement to achieve consistent results?

I am assuming that you are executing the query, retrieving the result set, fetching the row and extracting the value before the if statement (if not, then perhaps you need to do that first! Here is a start for PHP-MySql.
In case if you have already done that and forgot to mention this in your post (innocent until proven guilty I always say!! :) ), then could you provide us with more data on what are the different datasets when you got inconsistent results?

Try this
$ccquerycount = "SELECT * FROM payments_cc_info WHERE user_id=$userid";
$result = mysql_query($ccquerycount)
if (mysql_num_rows($result)==1) {
} else {
}
mysql_num_rows()
Get number of rows in result
Warning mysql_ extension is being deprecated . Instead, the MySQLi or PDO_MySQL extension should be used .

You can also add if condition inside of your mysql query like below.
SELECT
rating,
trade_service_id,
ifnull(round(sum(belonging_product_ratings.rating)/count(*),0),0) AS avg,
count(*) AS count
FROM
belonging_product_ratings WHERE trade_service_id != 0
GROUP BY
belonging_product_ratings.trade_service_id
other alternative is as below
select
BelongingProductRating.*,
User.*
from
belonging_product_ratings AS BelongingProductRating
LEFT OUTER JOIN
users AS User ON
IF( BelongingProductRating.rated_user_id != '$userID', BelongingProductRating.rated_user_id, BelongingProductRating.user_id) = User.id
You can say if condition inside mysql query is same as ternary if.
You can set query according to your php variable too.
I am sharing this code which i was ended up.
all you need to do is set it according to your table fields and conditions.
feel free to ask.

Related

PHP - Check if all entries in a table has the value 1 and then echo something

im currently stuck with an issue. Ive built a basic "team-work platform" in which you can set tasks in a to-do list. I've implemented the functionality that can mark a task as complete by setting the value of done to 1
I need to be able to check if all of the tasks in the list are set to done, and if so echo something. My code checks for the value 1, but it settles with a single entry being set to 1. But i need it to check if all tasks have the value 1 and if they do it should echo something.
$res3 = mysql_query("SELECT * FROM tasks WHERE tasks.planet_id=1 AND team_id=$teamid AND done=1")
or die(mysql_error());
if ($res3 && mysql_num_rows($res3) > 0)
{
echo 'Complete!';
}
else
{
echo 'Not done yet!';
}
I'll try to give you an example of how i want it to work: Lets say i have 10 tasks in the table. I want the code to recognise when all 10 of these tasks are marked as done with the value 1 set. And then echo "all your tasks are complete". So it needs to somehow loop through all the entries in the table and check if they are all set to 1, and when they are all set to 1 it echoes something.
Please help! :)
Assuming that done is an integer can can be either 0 or 1, you could do something like:
SELECT COUNT(*) total, SUM(done) totalDone FROM tasks WHERE tasks.planet_id=1 AND team_id=$teamid;
And then test in your PHP code that total == totalDone.
Alternatively, if you really want to only get a row out of the database when total == totalDone (as your comments seem to suggest), you could write something like this:
SELECT * FROM (SELECT COUNT(*) total, SUM(done) totalDone FROM tasks WHERE tasks.planet_id=1 AND team_id=$teamid) _X WHERE _X.total = _X.totalDone;
But that just adds a lot of extra complexity for no real gain, and I wouldn't recommend doing it that way.
Note that you should not use mysql_* functions in new code, and should instead use either mysqli or PDO. mysql_* is not recommended for new code.
Also, you should be careful with using variables directly in query strings. That can easily lead to sql injection vulnerabilities. Instead, use parameterized queries with mysqli or PDO.
The answer to 'all tasks done' is best done with the question of how many tasks where done <> 1.
I.e.
SELECT count(*) as 'incomplete'
FROM tasks
WHERE tasks.planet_id=1
AND team_id=$teamid and done <> 1;
Therefore you're able to use the code:
if($res3) {
$incompleteQueryResult = mysql_fetch_assoc($res3);
if ($incompleteQueryResult['incomplete'] > 0) {
echo "Not done yet";
} else {
echo "Complete!";
}
} else {
echo "Could not retrieve completed tasks";
}
If you still need to retrieve both the number of completed tasks as well as the number of incomplete, you could modify the query similar to the following.
SELECT
IF(done = 1, 'complete', 'incomplete') as status,
COUNT(*) AS 'number_in_status'
FROM tasks
WHERE tasks.planet_id=1
AND team_id=$teamid
GROUP BY done
And you'll need to modify how you retrieve it in the PHP as well if so.
If you need to know all of the above, then either execute two queries (one as an aggregate/summary and one as the full data set) or keep track of it in a variable. e.g.
$numIncompleteTasks = 0;
while($row = mysql_fetch_assoc($res3)) {
$numIncompleteTasks += ! (bool) $row['done'];
}
// you now know how many tasks are incomplete.
You could modify this code to track both complete and incomplete.
Deprecation notice.
I'd recommend reviewing your use of mysql_* functions - PHP deprecated and removed these functions in recent versions of PHP.
The answer from jbafford will not work in certains conditions.
Let's imagine we have only three possible values: 0,1 and 2. In the case of 0+1+2, the algorithm will say that COUNT = SUM, when in reality, we have a {0,1,2} and not {1,1,1}.
Why do I ask? Because I'm looking for a way in MYSQL to check if it is all ones, and I ruled out COUNT=SUM or in my case, taking the average, as I have this exception in my data.
A way to handle this exception is to add a COUNT DISTINCT. If COUNT DISTINCT=1 and COUNT=SUM, then the dataset is only 1s.

using mysqli_multi_query to set variables of data

I have just started to convert to mysqli due to the added security benefits. The main reason for converting to mysqli was the mysqli_multi_query function though. I had several long, complicated query's with a lot of JOINS in and when I found out about this function I thought I could make it simpler by breaking everything down into separate queries.
However, I have been unable to get the query to work as I want it to and the PHP manual isn't helping me.
Here's what I have so far;
$qry = "SELECT T.T_ID, T.name, T.pic, T.timestamp AS T_ts,
(SELECT COUNT(*) FROM track_plays WHERE T_ID = T.T_ID) AS plays,
(SELECT COUNT(*) FROM track_downloads WHERE T.T_ID = T_ID) AS downloads
FROM tracks T WHERE ID = '$ID';
";
$qry .= "SELECT S_ID, status, timestamp AS S_ts FROM status WHERE ID = '$ID';";
$qry .= "SELECT G_ID, gig_name, date_time, lineup, price, ticket, venue, G_pic, timestamp AS G_ts FROM gigs WHERE ID = '$ID'";
// Execute multi query
if (mysqli_multi_query($con,$qry)){
do {
// Store first result set
if ($result=mysqli_store_result($con)){
while ($row=mysqli_fetch_array($result)){
print_r($row);
}
}
}
while (mysqli_next_result($con));
}
This works fine and the array is printed as expected. However, i want to set a lot of variables for use later on. I won't list all of the variables but I have a few like this;
$S_ID = htmlspecialchars($row['S_ID']);
$T_ID = htmlspecialchars($row['T_ID']);
$G_ID = htmlspecialchars($row['G_ID']);
The variables are retrieved but due to the loop nature of the function PHP errors are given as well saying the $S_ID or $G_ID are undefined. $T_ID does not get an undefined error as it is the first query as is not looped over.
If you need any more information or I have not explained well enough just ask!
A while back ago i have had the same issues, and also for the same reason i have migrated from mysql to mysqli.
Sadly, it wasnt the best sollution for many cases, as i have realized on the way.
While implementing stuff with mysqli and multi query i still have had some issues that i had with mysql.
The solution i recommend, is to use views on your complicated querys.
it makes your coding and querys far less complicated.
I know it is not the answer you have been looking for, but give it a thought.
So far, every time I use a mysqli_multi_query, my do-while condition is:
while(mysqli_more_results($connection) && mysqli_next_result($connection));
You may like to replace your while statement and see if that helps.
If not, are you differentiating between each subsequent query when you are assigning these $S_ID, $G_ID variables? Are you inadvertently overwriting a variable with an empty $row[] value?
I also didn't see mysqli_free_result($result) in your code.
I'll even offer some error checking as a garnish.
preg_match_all("/(?:SELECT\s(.*?),\s.*?(?:;|$))/",$qry,$first_columnname);
if (mysqli_multi_query($con,$qry)){
do {
if ($result=mysqli_store_result($con)){
$query_identifier=array_shift($first_columnname[1]);
while ($row=mysqli_fetch_array($result)){
if($query_identifier)=="T.T_ID"){
//do something...
}elseif($query_identifier)=="S_ID"){
//do something...
}elseif($query_identifier)=="G_ID"){
//do something...
}
}
mysqli_free_result($result);
}
}
while(mysqli_more_results($con) && mysqli_next_result($con));
}
if($error_mess=mysqli_error($con)){echo "Error = $error_mess";}
Let me know if any of these small changes do the trick.

php code, better way of grabbing sql data

I need to grab data from two tables, but I know theres a better, more tidier way to do this. Is it some kind of JOIN i need?
I'll show you my code and you'll see what I mean:
if ($rs[firearm] != "") {
$sql_result2 = mysql_query("SELECT * FROM db_firearms WHERE name='$rs[firearm]'", $db);
$rs2 = mysql_fetch_array($sql_result2);
$sql_result3 = mysql_query("SELECT * FROM items_firearms WHERE player='$id'", $db);
$rs3 = mysql_fetch_array($sql_result3);
if ($rs3[$rs2[shortname]] < 1) {
mysql_query("UPDATE mobsters SET firearm = '' WHERE id ='$id'");
}
}
This question is clear, but your code example has alot of formatting issues and I cannot give you direct answer, based on your example code.
The reason, why your example is unclear, is because.. with what are you going to join the tables? From one table you are selecting by name='$rs[firearm]' and from another by player='$id'. You have to provide the hidden data, like $rs and also $id.
You should definitely read these about mysql join and mysql left join. But I will try to give you an example based on your code, with fixed syntax. (Keep in mind, that I'm no mysql join expert, I did not test this code and also I do not know the joining conditions.) And also, the system structure is unclear.
As I understood, this what your tables do, correct?
mobsters - Users table
items_firearms - Links from users table to items table
db_firearms - Items table
So basically, my example does this: It will have preloaded $rs value, from the users table. It will check, if there is a entry inside the links table and hook the result with them items table. However, if the links table or even the items table can return multiple entries, then this doesn't work and you need to loop your results in much more smarter way.
// I can only assume, that $id is the ID of the player
$id = 2;
// Since I dont know the $rs value, then Im going to make some up
$rs = array(
'id' => 33,
'firearm' => 'famas'
);
if ($rs['firearm']) {
$result = mysql_fetch_array(mysql_query("SELECT ifa.*, dbfa.* FROM `items_firearms` AS `ifa` LEFT JOIN `db_firearms` AS `dbfa` ON `ifa.shortname` = `dbfa.shortname` WHERE `ifa.player` = '$id'"));
if ($result['id']) {
mysql_query("UPDATE `mobsters` SET `firearm` = '' WHERE `id` = '$id'", $db);
}
}
It is pretty clear, that you are new to PHP and mysql.. So I think you should probably edit your question and talk about your higher goal. Briefly mention, what your application are you building..? What are you trying to do with the mysql queries..? Maybe provide the table structure of your mysql tables..? I'm sure, that you will get your questions votes back to normal and also we can help you much better.
NOTES
You have to quote these types of variables: $rs[firearm] -> $rs['firearm']
If you want to check if your $rs['firearm'] equals something, then there is a better way then $rs[firearm] != "". The most simple is if ($rs['firearm']) {echo 'foo';}, but will produce a notice message, when all errors reporting mode. You can use isset() and empty(), but keep in mind, that isset() checks whether the variable has been set.. Meaning, even if its false, then it has been set. empty() reacts to undefined and empty variable the same, without any messages.
Also, "" means NULL, so if you even need to use "", then use NULL instead...much neater way..
I strongly recommend to use mysql class. You can understand the basics behind that idea from this answer. This is gonna make things much more easier for you. Also, mysql class is a must-have when dealing with dynamic applications.
if ($rs3[$rs2[shortname]] < 1) { .. makes no sense.. Do you want to check if the value is empty? Then (simple): if (!$rs3[$rs2[shortname]]) { .. and a very strict standard: if (empty($rs3[$rs2[shortname]])) { ..
Also you have to quote your sql queries, see my examples above.
Is the last mysql query missing $db?

Can php query the results from a previous query?

In some languages (ColdFusion comes to mind), you can run a query on the result set from a previous query. Is it possible to do something like that in php (with MySQL as the database)?
I sort of want to do:
$rs1 = do_query( "SELECT * FROM animals WHERE type = 'fish'" );
$rs2 = do_query( "SELECT * FROM rs1 WHERE name = 'trout'" );
There is no MySQL function like this for PHP, however there is a more advanced substitute for it.
Edit: For those of you who don't know what a query of queries is, it's exactly this and there's a purpose some people do it like this. Using an AND operator is ****NOT**** the same thing! If I want results where username='animuson' for one part of my script and then want all the results out of that query where status='1', it is not logical for me to run another query using an AND operator, it is much more logical to loop through the previous results in PHP. Stop upvoting things without reading the comments on why they weren't upvoted in the first place, that's just lazy. If you don't have a clue what's being talked about, you shouldn't be upvoting or downvoting in the first place.
Well, you may want to do this without touching the db:
while($t = mysql_fetch_array($rs1)){
if($t[name] == 'trout'){
echo 'This is the one we\'re looking for!';
break;
}
}
In PHP, it would be terribly inefficient. You would have to loop through each row and check that its name was trout. However, is there any reason you can't do
SELECT * FROM `animals` WHERE `type` = 'fish' AND `name` = 'trout'
in SQL? It would be much, much faster.
You can also do something like
select morestuff from (select stuff from table where a = b ) where c = d;
Use the AND keyword?
"SELECT * FROM animals WHERE type = 'fish' and name='trout'"
Also, you can use LINQ for php http://phplinq.codeplex.com/

MySQL: Get only count of result set

I am using MVC with PHP/MySQL.
Suppose I am using 10 functions with different queries for fetching details from the database.
But at other times I may want to get only the count of the result that will be returned by the query.
What is the standard way to handle such situation.
Should I write 10 more functions which duplicate almost whole query and return only the count.
Or
Should I always return the count also with the result set
Or
I can pass a flag to indicate that the function should return count only, and then based on the flag I will dynamically generate the (select part of) query.
Or
Is there a better way?
Now that mysql supports sub-queries, you can get counts for any query using:
$count_query="SELECT COUNT(*) FROM ($query)";
How hard was that?
However this approach always means that you are running two queries instead of just the one (I'm not sure if MySQL would necessarily be able to use a cached result set for the count - try it out and see).
If you've already fetched the entire result set it'll probably be faster counting the rows in PHP than issuing another query.
There are 2 functions in MySQL which would return the number of matched rows prior to application of a limit statement:
SQL_CALC_FOUND_ROWS and FOUND_ROWS()
see
http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_found-rows
C.
If you want only number of rows matched certain criteria, you shouldn't use a count of the result, but another query that select only count(*) instead.
If you need both data and it's count, why don't you just use count() on the resulting array?
another way is to use some class that can return both data and it;s count, but not different classes for the each 10 queries but one single database access class.
I'd go with the flag idea.
Writing 10 more functions and copy/pasting code does not help readability at all. If you always also return the count, that means that whenever you're only interested in the count, the database still has to generate and transmit the full result set which might be grossly inefficient.
With the flag, you'd have something like
function getData($countOnly=false) {
// ...generate FROM and WHERE clause
if ($countOnly) {
$query = 'SELECT COUNT(*) '.$query;
} else {
$query = 'SELECT field1, field2, ...'.$query.' ORDER BY ...';
}
...
}
I would generally try to have as much code as possible shared between methods. A possibility would be to :
have one select() and one count() functions
each one building the specific part of the query
and one buildFromAndWhere() function to build the parts of the query that are common.
and have select() and count() use that one
Written in pseudo-code, it could look a bit like this :
function select($params) {
return "select * "
. from()
. where($params)
. "limit 0, 10";
}
function count() {
return "count(*) as nbr "
. from()
. where();
}
function from() {
return "from table1 inner join table1 on ... ";
}
function where($params) {
// Use $params to build the where clause
return "where X=Y and Z=blah";
}
This way, you have as much common code as possible in the from() and where() functions -- considering the hard part of the queries is often there, it's for the best.
I prefer having two separate functions to select and count ; I think it make code easier to read and understand.
I don't like the ideas of one method returning two distinct data (list of results and the total count) ; and i don't really like the idea of passing a flag either : looking at the function's call, you'll never know what that parameter means.

Categories