counting null columns Mysql using PHP - php

I am wanting to count the null columns or with a certain value
$q = mysql_query("
SELECT SUM(
(`foto` = 'avatar_small.png') +
(`email` IS NULL) +
(`cidade` IS NULL) +
(`estado` IS NULL) +
(`endereco` IS NULL) +
(`numero` IS NULL) +
(`cep` IS NULL) +
(`telefone` IS NULL)
) FROM `info_complementos` WHERE id_user = ".$_SESSION['usuario_cargo']) or die(mysql_error());
$retorno = mysql_num_rows($q);
return $retorno[0];
the problem is that it shows the result

You can use the COUNT function in mysql to count the rows returned. So you want to filter out the rows that you do not want in the WHERE clause. This will count all the rows that match ALL the conditions. You can change the AND to OR if you want to match rows that contain some NULL values.
<?php
$q = mysql_query("
SELECT COUNT(*) FROM `info_complementos`
WHERE
id_user = $_SESSION['usuario_cargo'] AND
`foto` = 'avatar_small.png' AND
`email` IS NULL AND
`cidade` IS NULL) AND
`estado` IS NULL) AND
`endereco` IS NULL AND
`numero` IS NULL AND
`cep` IS NULL AND
`telefone` IS NULL");
$result = mysql_fetch_array($q);
echo $result[0];
Hope this helps.

Related

How can I get Filled(columns that have not Empty and Not Null Values) Columns Count in MySQL?

Can anyone please help me get the count of the filled MySQL columns?
For example:
My Table Structure:
ID
FName
LName
1
ABC
NULL
2
XYZ
In the above table, I have two Rows, and both rows contain one Null and One Empty Value, I just need to get the Count of each row that doesn't have NULL OR EMPTY Value for a specific ID.
Expected Result:
WHERE ID=1, the result would be:
Count = 2 (ID, FName)
WHERE ID=2, the result would be:
Count = 2 (ID, LName)
**I want to use this in WordPress
So, after searching for an hour or two.
I'm using this as my solution but I'm not sure if it's good regrading the optimization. Here is what I'm using:
function ranking_mechanism( $currentUserID ){
global $wpdb;
$rank = 0;
$results = $wpdb->get_row(
$wpdb->prepare('SELECT * FROM TABLE WHERE ID=%d', $currentUserID)
);
$finalArr = (array) $results; // Convert $results as Array(to perform iteration), it(WordPress DB Query) typically return Object by Default
foreach ( $finalArr as $key => $Table ) {
if( $finalArr[$key] == '' || $finalArr[$key] == 'NULL' ){
// Nothing to do
}else{
$rank = $rank+1; // Increase Rank If Found Value
}
return $rank;
}
SELECT ID, (ID IS NOT NULL) /* assuming that ID is numeric and cannot be empty string */
+ (FName <> '' AND FName IS NOT NULL)
+ (LName <> '' AND LName IS NOT NULL) AS `Count`
FROM source_table
-- WHERE ID = ???

Foreach iteration only returning last value from last loop

I'm trying to grab and count all the replies for each post for example all the replies for a specific post are labeled 2 under the column level but my foreach loop only grabs the value from the last iteration. For, example lets say I want all the comment replies from post_id 91 which has the comments 92 95 for their post_id which in turn has the replies 93 94 96 for their post_id. My foreach loop only returns the last replies post_id 96 but I want my foreach loop to save all the posts comments replies post ids for example, it should return all the post ids 93 94 96. I was wondering what do I need to change in my code to achieve this please help. Thanks.
MySQL Table Structure
CREATE TABLE posts(
post_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
parent_id INT UNSIGNED NOT NULL DEFAULT 0,
member_id INT UNSIGNED NOT NULL,
profile_id INT UNSIGNED NOT NULL,
level INT UNSIGNED NOT NULL DEFAULT 0,
post LONGTEXT DEFAULT NULL,
date_created DATETIME NOT NULL,
date_updated DATETIME DEFAULT NULL,
update_count INT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (post_id)
);
MySQL Table Data
post_id parent_id member_id profile_id level post date_created date_updated update_count
96 95 1 1 2 reply 1 for comment 2 2017-08-06 02:26:09 NULL 0
95 91 1 1 1 comment 2 2017-08-06 02:25:43 NULL 0
94 92 1 1 2 reply 2 2017-08-06 02:25:09 NULL 0
93 92 1 1 2 reply 1 2017-08-06 02:25:00 NULL 0
92 91 1 1 1 comment 1 2017-08-06 02:24:47 NULL 0
91 0 1 1 0 post 1 2017-08-06 02:24:31 NULL 0
PHP
//grab the all the post comments replies
function grab_all_post_comment_replies_parent_ids($post_id){
//filter string to contain only numbers just in case
$post_id = filter_numbers($post_id);
//escape special characters in the string for use in the MySQL statement
$post_id = mysqli_real_escape_string(database(), $post_id);
$query = "SELECT `posts`.`post_id`
FROM `posts`
WHERE `parent_id` = '$post_id'
AND `level` = '1'";
//short hand if statement ? if-true : if-false to determine the number of results returned by the query
$count = ($query = mysqli_query(database(), $query)) ? mysqli_num_rows($query) : 0;
if($count === 0){
//query returned 0 meaning no results so return false as the value for the function
return false;
} else {
while($row = mysqli_fetch_array($query)){
$results[] = $row['post_id'];
}
return $results;
}
}
function all_post_comment_replies($post_id){
$total = count(grab_all_post_comment_replies_parent_ids($post_id));
$sum = 0;
$all_ids = array();
if(is_array(grab_all_post_comment_replies_parent_ids($post_id))){
foreach(grab_all_post_comment_replies_parent_ids($post_id) as $parent_id){
//filter string to contain only numbers just in case
$parent_id = filter_numbers($parent_id);
//escape special characters in the string for use in the MySQL statement
$parent_id = mysqli_real_escape_string(database(), $parent_id);
$query = "SELECT *
FROM `posts`
WHERE `parent_id` = '$parent_id'
AND `level` = '2'";
//short hand if statement ? if-true : if-false to determine the number of results returned by the query
$count = ($query = mysqli_query(database(), $query)) ? mysqli_num_rows($query) : 0;
if($count === 0){
//query returned 0 meaning no results so return false as the value for the function
return false;
} else {
while($row = mysqli_fetch_array($query)){
$ids[] = $row['post_id'];
}
$all_ids = $ids;
}
if($sum = $total){
return $all_ids;
} else {
return false;
}
$sum++;
}
} else {
return false;
}
}
The problem
In the foreach loop, you looped while $parent_id was in grab_all_post_comment_replies_parent_ids($post_id). However, what you forgot was that at the end of each loop, the condition in the foreach loop is checked again.
Thus, every time the foreeach loop ended, you called that function again, it replaced the current array with the new one, and thus we're searching through a new array from the start, and thus you only got the first result.
What I have done here is run the function once at the start, and then store it to a variable. Now it will loop through each value in the array without a problem.
Secondly, there is no need for the bit where you check the sum and its total. The foreach loop will always end, and you can return the values when it does. At the moment though, you are simply checking is 0 == total, which it will not be, and then returning without giving your loop a chance to keep running.
Simply remove it, and return at the end.
The Solution
function all_post_comment_replies($post_id){
$parent_ids = grab_all_post_comment_replies_parent_ids($post_id);
$total = count($parent_ids);
$all_ids = array();
if(is_array($parent_ids)){
foreach($parent_ids as $parent_id){
//filter string to contain only numbers just in case
$parent_id = filter_numbers($parent_id);
//escape special characters in the string for use in the MySQL statement
$parent_id = mysqli_real_escape_string(database(), $parent_id);
$query = "SELECT *
FROM `posts`
WHERE `parent_id` = '$parent_id'
AND `level` = '2'";
//short hand if statement ? if-true : if-false to determine the number of results returned by the query
$count = ($query = mysqli_query(database(), $query)) ? mysqli_num_rows($query) : 0;
if($count === 0){
//query returned 0 meaning no results so return false as the value for the function
return false;
} else {
while($row = mysqli_fetch_array($query)){
$ids[] = $row['post_id'];
}
$all_ids = $ids;
}
}
return $all_ids;
} else {
return false;
}
}
In the function all_post_comment_replies() there are this error :
if($sum = $total){ // assigment, not comparison
return $all_ids;
} else {
return false;
}
In if sentence, the $total variable is assigned to $sum.
No comparison expression and is always true ($sum is always >0), it's only false when expression is equal to zero.
I think it iterate only one time.
Fix with :
if($sum == $total){ // see ==
return $all_ids;
} else {
return false;
}

Laravel 5 raw query to query builder

I have bellow raw mysql query, what i want to do is to change this to query builder. need help.
SET #groupIds = '11,14';
SET #eventIds = '13,5';
SET #friendIds = '1000022';
SET #userFollowings = '1000001';
$query = "SELECT sn_posts.*
FROM sn_posts
WHERE
sn_posts.deleted_at is null AND
(
sn_posts.user_id = '1000042' OR (
(
IF(#groupIds is not null AND #groupIds <> '',FIND_IN_SET(sn_posts.postable_id,#groupIds),0)
OR IF(#eventIds is not null AND #eventIds <> '',FIND_IN_SET(sn_posts.postable_id,#eventIds),0)
OR IF(sn_posts.privacy_level = 0, (
IF(#friendIds is not null AND #friendIds <> '', FIND_IN_SET(sn_posts.`user_id`,#friendIds),0)
OR IF(#userFollowings is not null AND #userFollowings <> '',FIND_IN_SET(sn_posts.`user_id`,#userFollowings),0)
),
IF(#friendIds is not null AND #friendIds <> '', FIND_IN_SET(sn_posts.user_id,#friendIds),0)
)
)
AND IF(sn_posts.`parent_id` IS NOT NULL,(
SELECT parent.id FROM sn_posts AS parent
WHERE parent.id = sn_posts.`parent_id` AND IF(parent.privacy_level = 0,1,IF(#friendIds is not null AND #friendIds <> '', FIND_IN_SET(parent.`user_id`,#friendIds),0))
),1)
)
)
ORDER BY sn_posts.created_at desc
LIMIT 21,10";
$result = DB::raw(DB::select($query));
I have php variables instead of those mysql variables.
Because of need for result as collection, i need a way to get the result as collection.
What I have tried:
$result = Post::where('deleted_at', null)
->where(function($query) use($authUserID,$friendIds,$userFollowings,$groupIds,$eventIds) {
$query->where('user_id', $authUserID);
orWhere(function($query) use($friendIds,$userFollowings,$groupIds,$eventIds) {
$query->whereIn('postable_id', $groupIds)
->orWhereIn('postable_id', $eventIds)
->orWhere(function($query) use ($friendIds, $userFollowings) {
if ($query->where('privacy_level', 0)) {
$query->whereIn('user_id', $friendIds)
->orWhereIn('user_id', $userFollowings);
} else {
$query->whereIn('user_id', $friendIds);
}
});
})->where(function($query) use($friendIds){
***if ($query->whereNotNull('parent_id')) {
DB::raw('select parent.id from sn_posts as parent where parent.id = '.$query->parent_id.'
and if(parent.privacy_level = 0,1,
if('.$friendIds.' is not null and '.$friendIds.' <> "", FIND_IN_SET(parent.user_id, '.$friendIds.'), 0))
}***
});
});
The main problem is on checking access level of parent post (between stars blocks) of current shared post. It means i want to check if current post is a shared post, then check if it is parent is a public post, or it is a post from my friends, then get that shared post, else escape.

Select COUNT where field NOT NULL, for each field of the table

I have a table with a lot of fields, and I need to return the COUNT of NOT NULL for each field.
I make a loop in PHP and I execute 1 request by field...
$result = array();
$champs = array("field1", "field2", "field3", "field4", "field5", "field6", "field7", "field8", "field9", "field10", "field11", "field12", "field13", "field14", "field15", "field16", "field17", "field18", "field19", "field20");
foreach ($champs as $value) {
$and = empty($filtroAdd) ? "$value IS NOT NULL" : "AND $value IS NOT NULL";
$requete = "SELECT COUNT($value)
FROM my_table
WHERE $filtroAdd $and";
$r = $db->query($requete)->fetch(PDO::FETCH_NUM);
$result[$value] = $r[0];
}
print_r( $result );
I think it is not the better way, and we surely can return the same final result with a single postgreSQL request ?!
Thanks for help
You can use a single query:
SELECT COUNT(field1), COUNT(field2), COUNT(field3), . . .
FROM my_table;
There is no need to do a separate query for each field. COUNT(<field>) returns the number of rows with non-NULL values in that column.
If you want the number of different values, then use COUNT(DISTINCT):
SELECT COUNT(DISTINCT field1), COUNT(DISTINCT field2), COUNT(DISTINCT field3), . . .
FROM my_table;
You can also embed CASE logic, if you like. I usually do this using SUM():
SELECT SUM(CASE WHEN field1 > 0 THEN 1 ELSE 0 END),

PHP and MySQL problems

I'm trying to count how many times a certain article has been graded for example how many times have users_articles_id 3 been graded by my members.
I'm also trying to count the points for a certain article for example users_articles_id 3 is related to the ratings database by its ratings_id the rating points should be a total of 13.
I was wonder if I was doing this right because to me it looks all wrong? I was hoping if some one can help me fix this? And where should my code go exactly?
I'm using PHP and MySQL?
Here is my MySQL tables
CREATE TABLE articles_grades (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
ratings_id INT UNSIGNED NOT NULL,
users_articles_id INT UNSIGNED NOT NULL,
user_id INT UNSIGNED NOT NULL,
date_created DATETIME NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE ratings (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
points FLOAT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (id)
);
Database Input
articles_ratings
id ratings_id users_articles_id user_id date_created
1 3 2 32 2010-01-13 02:22:51
2 1 3 3 2010-01-13 02:23:58
3 2 3 45 2010-01-13 02:24:45
ratings
id points
1 10
2 3
3 5
Here is the PHP code I'm trying to fix.
// function to retrieve rating
function getRating(){
$sql1 = "SELECT COUNT(*)
FROM articles_ratings
WHERE users_articles_id = '$page'";
$result = mysql_query($sql1);
$total_ratings = mysql_fetch_array($result);
$sql2 = "SELECT COUNT(*)
FROM ratings
JOIN ratings ON ratings.id = articles_ratings.ratings_id
WHERE articles_ratings.users_articles_id = '$page'";
$result = mysql_query($sql2);
$total_rating_points = mysql_fetch_array($result);
if(!empty($total_rating_points) && !empty($total_ratings)){
// set the width of star for the star rating
$rating = (round($total_rating_points / $total_ratings,1)) * 10;
echo $rating;
} else {
$rating = 100;
echo $rating;
}
}
Well I think there are several issues here.
1) You are defining a table called articles_grades, not articles_ratings, as in your code.
2) Why do articles_grades and ratings need to be in separate tables? There is a one-to-one correspondence between those tables.
3) You need to do sum(points) in your second query.
4) You can combine both queries into a single query.
Here's how I would do it if you don't change the schema:
<?php
mysql_connect('localhost','root','fake123123');
mysql_select_db('test');
$result = mysql_query('SELECT users_articles_id,count(*),sum(r.points)
FROM articles_grades ag,ratings r
WHERE ag.ratings_id = r.id
GROUP BY users_articles_id');
if (!$result)
die('invalid');
else{
echo '<table><tr><th>Article Id</th><th>#Ratings</th><th>#Points</th></tr>';
$a = mysql_fetch_row($result);
while($a){
echo '<tr><td>'.implode('</td><td>',$a).'</td></tr>';
$a = mysql_fetch_row($result);
}
echo '</table>';
}
?>
You can run this as a CGI script. It should return a table of the results.
Let me know if this helps.

Categories