Count Not Null Columns using PHP - php

i have a table "tbl_userpersonal",
what i want to achieve is check which columns are filled and which are not so i can calculate or display the profile completion percentage.
\
So far i've tried a lot of different techniques and codes and my code is counting all columns but i want it to count empty value columns as 0.
please help me with a solutions.
So far if there is even a single entry for a user in any column it's giving me 100% otherwise 0% there is no inbetween
Currently if there is value inside "father_name" & "mother_name" & "DOB" column for a user with user_authtoken = "app_7837hfjd57hdj" the expected output should be
3
50% i.e (3/6)*100
what is happening right now is
if there is value inside either of these columns for a user with user_authtoken = "app_7837hfjd57hdj" the output is showing as
6
100% i.e (6/6)*100
or if there is no entry for user with user_authtoken = "app_7837hfjd57hdj" the output is giving
0
0%
here is the php code
$personal = mysqli_query($con,"
SELECT father_name,
mother_name,
DOB,
adhar_no,
address,
religion,
CASE WHEN father_name IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN mother_name IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN DOB IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN adhar_no IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN address IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN religion IS NOT NULL THEN 1 ELSE 0 END AS personal
FROM user WHERE `user_authtoken` = '$user_ath'
") or die(mysqli_error($con));
$data=mysqli_fetch_assoc($personal);
$pro_count = $data['personal'];
echo $pro_count ;
echo '<br>';
$percentage = ($pro_count /6)*100;
echo $percentage;

i think you have empty value in table not null try this
this will check for null as well as empty
$personal = mysqli_query($con,"
SELECT father_name,
mother_name,
DOB,
adhar_no,
address,
religion,
CASE WHEN father_name IS NOT NULL AND father_name<>'' THEN 1 ELSE 0 END +
CASE WHEN mother_name IS NOT NULL AND mother_name<>'' THEN 1 ELSE 0 END +
CASE WHEN DOB IS NOT NULL AND DOB<>'' THEN 1 ELSE 0 END +
CASE WHEN adhar_no IS NOT NULL AND adhar_no<>'' THEN 1 ELSE 0 END +
CASE WHEN address IS NOT NULL AND address<>'' THEN 1 ELSE 0 END +
CASE WHEN religion IS NOT NULL AND religion<>'' THEN 1 ELSE 0 END AS personal
FROM user WHERE `user_authtoken` = '$user_ath'
") or die(mysqli_error($con));

Related

How to select a case with sum operator in laravel

I have this query that sums values from different columns when they have a id active like id_test = 1 note_test = 11, it has a case stament if the id is in 0
this is the query
select
case when id_test1 = 1 then note_test1 else 0 end +
case when id_test2 = 1 then note_test2 else 0 end +
case when id_test3 = 1 then note_test3 else 0 end +
case when id_test4 = 1 then note_test4 else 0 end +
case when id_test5 = 1 then note_test5 else 0 end +
case when id_test6 = 1 then note_test6 else 0 end +
case when id_test7= 1 then note_test7 else 0 end as total_weighted
from rp_student where id = 1
This is my query in laravel
$weighted= DB::table('rp_student')
->select(DB::raw('case when id_test1 = 1 then note_test1 else 0 end +
case when id_test2 = 1 then note_test2 else 0 end +
case when id_test3 = 1 then note_test3 else 0 end +
case when id_test4 = 1 then note_test4 else 0 end +
case when id_test5 = 1 then note_test5 else 0 end +
case when id_test6 = 1 then note_test6 else 0 end +
case when id_test7= 1 then note_test7 else 0 end as total_weighted'))
->where('id','=',1);
It doesn't return me any value
Your query is missing the required ->get() at the end. The reason why your don't see a value currently is the query hasn't actually been executed.
The get method returns an Illuminate\Support\Collection containing the results where each result is an instance of the PHP stdClass object. You may access each column's value by accessing the column as a property of the object:
https://laravel.com/docs/5.8/queries#retrieving-results

PHP, sql query to CSV, format rows for totals

I have a working script that, when executed, runs the following SQL query which is then written to a CSV. All of this works perfectly.
However, I'd like to adjust the formatting somewhat. It currently writes results by employee and orders by last night. I'd like to have a row at the end of all agent's records that said something like "Agent's Name: Totals" and then sums up the totals of their records.
For example, each row has their name, phone extension, and then several metrics which are either blank or have an 'x', and lastly a number representing time on the phone. So I'd like to total the x's in the appropriate fields, add the duration of time on the phone, and lastly a count of total calls (which would be a count of that employee's records).
I don't know if this should be done in the SQL, in the CSV code block or if there's a better way to store the metrics with PHP and do this programmatically.
I'm a rookie here, normally just relying on queries in MySQL workbench, so any help is much appreciated.
Here's the script:
$result = mysqli_query($conn2,
"SELECT
firstn
, lastn
, extension
, Recieved
, RecievedKnown
, Outbound
, outboundKnown
, Missed
, MissedKnown
, CallingNumber
, CalledNumber
, starttime
, endtime
, duration
, HOLDTIMESECS
, TERMINATIONREASONCODE
FROM (
SELECT
u.firstn
, u.lastn
, c.extension
, CASE WHEN LEGTYPE1 = 2 AND ANSWERED = 1 THEN 'x' ELSE '' END AS Recieved
, CASE WHEN LEGTYPE1 = 2 AND answered = 1 AND CALLINGPARTYNO = k.phone_number THEN 'x' ELSE '' END AS RecievedKnown
, CASE WHEN ANSWERED = 1 AND LEGTYPE1 = 1 THEN 'x' ELSE '' END AS Outbound
, CASE WHEN LEGTYPE1 = 1 AND FINALLYCALLEDPARTYNO = k.phone_number THEN 'x' ELSE '' END AS outboundKnown
, CASE WHEN Answered = 0 THEN 'x' ELSE '' END AS Missed
, CASE WHEN ANSWERED = 0 AND CALLINGPARTYNO = k.phone_number THEN 'x' ELSE '' END AS MissedKnown
, a.CALLINGPARTYNO AS CallingNumber
, a.FINALLYCALLEDPARTYNO AS CalledNumber
, b.starttime AS starttime
, b.endtime AS endtime
, b.duration
, a.holdtimesecs
, a.terminationreasoncode
FROM ambition.session a
INNER JOIN ambition.callsummary b ON a.NOTABLECALLID = b.NOTABLECALLID
INNER JOIN ambition.mxuser c ON a.RESPONSIBLEUSEREXTENSIONID = c.EXTENSIONID
INNER JOIN jackson_id.users u ON c.extension = u.extension
LEFT JOIN ambition.known_numbers k ON a.callingpartyno = k.phone_number
WHERE date(b.ts) >= curdate()
AND LEGTYPE1 <> 12 -- This keeps the report from having blank spaces due to the 12 legtype.
AND c.extension IN (7276,7314,7295,7306,7357,7200,7218,7247,7331,7255,7330,7000,7215,7240,7358,7312)
) x
ORDER BY lastn") or die(mysqli_error( $conn2));
$userDetails = array();
while($row = $result->fetch_array(MYSQLI_NUM)){
/* Let me take the extension as the key to store its respective counts */
$extension = $row['extension'];
/* Now in your while loop do all the calculations for the user */
if(!isset($userDetails[$extension])){
/* Since this is the first time for the extension your doin the calculations */
$userDetails[$extension]['missedCallCounts'] = 1; /* First time count */
}else{
$userDetails[$extension]['missedCallCounts'] += 1; /* Sum up the count */
}
}
foreach($userDetails as $userDetail){
/* In the following line dump the respective userdetails to csv which will show summary */
fputcsv($fp, array_values($userDetails));
}
And a screenshot of the current CSV results in excel (omitted names/numbers, but you still see the idea):
So for extension 7312, under the first two rows would be a new row with something like:
7312's Totals | 0 | 0 | 0 | 0 | 2 | 2 | - | - | - | - | 76 | 0
Your looping into the sql query to output the same to CSV file, at that time keep the records in generic array and dump once the loop gets over.
For Eg:
$userDetails = array();
while($row = $result->fetch_array(MYSQLI_NUM)){
/* Let me take the extension as the key to store its respective counts */
$extension = $row['extension'];
/* Now in your while loop do all the calculations for the user */
if(!isset($userDetails[$extension])){
/* Since this is the first time for the extension your doin the calculations */
$userDetails[$extension]['missedCallCounts'] = 1; /* First time count */
}else{
$userDetails[$extension]['missedCallCounts'] += 1; /* Sum up the count */
}
}
Now loop into the $userDetails and dump the same to CSV
foreach($userDetails as $userDetail){
/* In the following line dump the respective userdetails to csv which will show summary */
fputcsv($fp, array_values($userDetails));
}

Mysql count column issue

I can't figure-it out how to count all these dancers columns and echo with total of all dancers
id | dancer1 | dancer2 | dancer3 | dancer4, and so on..
---------------------------------------
1 alex michael dalm name
2 clare rose test
I have this for the start but is not working:
$counter = mysql_query("SELECT COUNT(*) AS id FROM table");
$num = mysql_fetch_array($counter);
$dancers = $num["id"];
echo "Total dancers: $dancers";
Any help is appreciated. Thanks!
Try this:
$counter = mysql_query("SELECT * FROM table");
$dancers = 0;
while($rows = mysql_fetch_array($counter)){
for($i = 1; $i <= 24; $i++){
$dan_id = 'dancer'.$i;
if($rows[$dan_id] != "" || $rows[$dan_id] != null )
$dancers++;
}
}
echo "Total dancers:". $dancers;
Note: Never design your database table like this.
I would actually save your dancers in a different (easier) way... For examle:
ID NAME SURNAME PHONE ....
1 Anna Brickstone 0975 ...
2 Jef Damen 0754 ...
That way you could use the following code to count tables:
$dancersCount="0";
$sql = "SELECT * FROM dancers";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$dancersCount++;
}
} else {
echo "No dancers..";
}
echo"$dancersCount";
The counter will count +1 each time it finds a row (dancer)
If you really want to do it that way...
Then I don't really think there's an easy way to fix this... You will probably need to check how many columns you have in your database but that's not something i can help you with...
You need to change your table structure:
id | dancerNumber | name
1 1 alex
2 1 clare
3 2 michael
4 2 rose
5 3 dalm
6 3 test
7 4 name
8 4 dana
SELECT COUNT(*) AS id FROM table will return 8 dancers. If this is what you were looking for?
if you want to keep your structure then you need to do the following sql query
SELECT dancer1,
dancer2,
dancer3,
(CASE WHEN (dancer1 <> "" AND dancer1 IS NOT NULL) THEN 1 ELSE 0 END +
CASE WHEN (dancer2 <> "" AND dancer2 IS NOT NULL) THEN 1 ELSE 0 END +
CASE WHEN (dancer3 <> "" AND dancer3 IS NOT NULL) THEN 1 ELSE 0 END) AS COUNTER
FROM table
This will count all the non empty and non null columns and add a counter at the end of the table. this counter will then contain the number of dancers with your structure.
Full answer with your php code
$query = 'SELECT (CASE WHEN (dancer1 <> "" AND dancer1 IS NOT NULL) THEN 1 ELSE 0 END +
CASE WHEN (dancer2 <> "" AND dancer2 IS NOT NULL) THEN 1 ELSE 0 END +
CASE WHEN (dancer3 <> "" AND dancer3 IS NOT NULL) THEN 1 ELSE 0 END) AS COUNTER
FROM table'
$counter = mysql_query($query);
$num = mysql_fetch_array($counter);
$dancers = $num["COUNTER"];
echo "Total dancers: $dancers";

Using Triggers and Procedures to change active inventory

First starting with this table:
Table estoque_folha
And your records:
Records
My complete database code : pastebin.com/v30s9Aa1
I wanted to know how a trigger / procedure for when the quantidade field is zero, the line stow with fild ativo == 1 , it zero to set this record and after it to set 1 in the ativo field where the espera field is 1 . That is:
When quantidade == 0 where ativo == 1, to set ativo == 0 and then looking where espera == 1 and set ativo == 1
At the moment I have this trigger, that when the inventory is zero, disables and adds date in the field data_saida
CREATE TRIGGER `tr_setaDataeDesativa` BEFORE UPDATE ON `estoque_folha`
FOR EACH ROW
IF NEW.quantidade = 0 THEN
SET NEW.data_baixa = current_date;
SET NEW.ativo = '0';
ELSEIF NEW.quantidade > 0 THEN
SET NEW.data_baixa = 0000-00-00;
END IF
I need to create another trigger or can take advantage of this?
Thank you

How can you use CASE Statements to assign values to matches in your query?

Let's say your running a query and you have a lot of different user inputs that may not find an exact match. Now would it be possible to do something like the following?
$query = "SELECT *,
CASE matchingValues
WHEN $field1 LIKE '$a' THEN value = '1' ELSE value = '0'
WHEN $field2 LIKE '$b' THEN value = '1' ELSE value = '0'
WHEN $field3 LIKE '$c' THEN value = '1' ELSE value = '0'
WHEN $field4 LIKE '$d' THEN value = '1' ELSE value = '0'
WHEN $field5 LIKE '$e' THEN value = '1' ELSE value = '0'
END AS score
FROM . $usertable
WHERE
$field1 LIKE '$a' AND
$field2 LIKE '$b' AND
$field3 LIKE '$c' AND
$field4 LIKE '$d' AND
$field5 LIKE '$d'
ORDER BY score DESC";
if($result = mysql_query($query)) {
if(mysql_num-rows($result)==NULL) {
echo 'No Results Found';
}else{
....
Yes this is possible, though you would do it without the WHERE clause, and you would want to add up all the inputs instead of using a CASE to get the total score. Since each LIKE statement returns a boolean 1 or 0, you can just add them up to find out how many matches you have. A HAVING clause then limits to rows returned with a score > 0, if you want to return only those that actually matched.
SELECT *,
(($field1 LIKE '$a') +
($field2 LIKE '$b') +
($field3 LIKE '$c') +
($field4 LIKE '$d') +
($field5 LIKE '$e')) AS score
FROM . $usertable
HAVING score > 0
ORDER BY score DESC";
We assume you have already added % wildcards to the LIKE variables, and that they have been properly escaped prior to use in your query.
However, while you can do it this way (a poor-man's full-text search), MySQL offers the possibility of creating a full text index across multiple columns on MyISAM tables.
Update: To artificially weight them...
If you have a need to weight them, use CASE statements and put in higher numbers for the top few:
SELECT *,
(CASE WHEN ($field1 LIKE '$a') THEN 5 ELSE 0 END +
CASE WHEN ($field2 LIKE '$b') THEN 4 ELSE 0 END +
CASE WHEN ($field3 LIKE '$c') THEN 3 ELSE 0 END +
CASE WHEN ($field4 LIKE '$d') THEN 2 ELSE 0 END +
CASE WHEN ($field5 LIKE '$e') THEN 1 ELSE 0 END) AS score
FROM . $usertable
HAVING score > 0
ORDER BY score DESC";
To just enforce that the first one match, put it in your WHERE clause.
SELECT *,
(($field1 LIKE '$a') +
($field2 LIKE '$b') +
($field3 LIKE '$c') +
($field4 LIKE '$d') +
($field5 LIKE '$e')) AS score
FROM . $usertable
WHERE $field1 LIKE '$a'
HAVING score > 0
ORDER BY score DESC";
Again, to be clear - a very closely related functionality is already built-in and optimized in MySQL's full text indexing and the MATCH keyword.

Categories