Combine Multiple Select Count Queries on same table - php

I have a table with a bunch of order rows in it. I need to check the table to see if there's 1 or more rows matching 2 WHERE clauses. If there is, I set a variable to 'yes' that I use elsewhere on the page.
Currently I'm checking this with individual php mysql queries but wondering if it's possible to combine them into a single select query so i'm hitting the database one time rather than like 10 or more times.
Here's an example of the current code:
$query9 = "SELECT COUNT(*) as num FROM mojave_requests where status = 'Pending' AND local = 'L-BKED'";
$requestEDI = mysql_fetch_array(mysql_query($query9));
$requestEDI = $requestEDI[num];
if ($requestEDI> 0) {
$requestsEDI = 'yes';
}
$query11 = "SELECT COUNT(*) as num FROM mojave_requests where status = 'Pending' AND local = 'LOQ53'";
$requestLOQ53 = mysql_fetch_array(mysql_query($query11));
$requestLOQ53 = $requestLOQ53[num];
if ($requestLOQ53 > 0) {
$requestsLOQ53 = 'yes';
}
$query13 = "SELECT COUNT(*) as num FROM mojave_requests where status = 'Pending' AND local = 'L-YRYR'";
$requestLYRYR = mysql_fetch_array(mysql_query($query13));
$requestLYRYR = $requestLYRYR[num];
if ($requestLYRYR > 0) {
$requestsLYRYR = 'yes';
}
$query15 = "SELECT COUNT(*) as num FROM mojave_requests where status = 'Pending' AND local = 'L-CAL0611'";
$requestLCAL0611 = mysql_fetch_array(mysql_query($query15));
$requestLCAL0611 = $requestLCAL0611[num];
if ($requestLCAL0611 > 0) {
$requestsLCAL0611 = 'yes';
}
The only two things different between each query is the "local" column string I'm checking and the variable name I set to "Yes" if there's at least 1 match.
Thanks for looking.

You can use conditional sum as
SELECT
sum
(
case when status = 'Pending' AND local = 'L-BKED' then 1 else 0 end
) as `L-BKED_COUNT`,
sum
(
case when status = 'Pending' AND local = 'LOQ53' then 1 else 0 end
) as `LOQ53_COUNT`,
sum
(
case when status = 'Pending' AND local = 'L-YRYR' then 1 else 0 end
) as `L-YRYR_COUNT`,
sum
(
case when status = 'Pending' AND local = 'L-CAL0611' then 1 else 0 end
) as `L-CAL0611_COUNT`
FROM mojave_requests

This GROUP BY SELECT will give you the count for local matching the values that you need:
SELECT COUNT(*) as num,
local
FROM mojave_requests
WHERE status = 'Pending'
GROUP BY local
HAVING local IN ('L-BKED','LOQ53','L-YRYR','L-CAL0611')
SQL Fiddle
You should also change your PHP code and do not use those $request___ variables, but only a while cycle to check:
$result = mysql_query($sql);
while ($row = mysql_fetch_array($result)) {
switch ($row[1]) {
case 'L-BKED':
code to be executed if count for L-BKED > 0
break;
case 'LOQ53':
code to be executed if count for LOQ53 > 0
break;
case 'L-YRYR':
code to be executed if count for L-YRYR> 0
break;
...
}
}

You are looking for conditional aggregation. The simplest way to do this in MySQL is to take advantage of the fact that booleans are treated as numbers in a numeric context:
SELECT SUM(status = 'Pending' AND local = 'L-BKED') as num_bked,
SUM(status = 'Pending' AND local = 'LOQ53') as num_loc53,
SUM(status = 'Pending' AND local = 'L-YRYR') as num_yryr,
SUM(status = 'Pending' AND local = 'L-CAL0611') as num_cal0611
FROM mojave_requests;
This returns the values in one row. You can fetch the values by referencing the columns in php.
You can simplify this query by factoring out the first condition:
SELECT SUM(local = 'L-BKED') as num_bked,
SUM(local = 'LOQ53') as num_loc53,
SUM(local = 'L-YRYR') as num_yryr,
SUM(local = 'L-CAL0611') as num_cal0611
FROM mojave_requests
WHERE status = 'Pending';
If few of the status values are actually PENDING, then an index on mojave_requests(status, local) should noticeably improve performance.

Related

How to count contents of last n rows mysql

I am trying to figure out how to see how many times in the past 7 entries/rows that sleep = 1.
Currently, $num shows the number of times sleep = 1 in all rows. I have seen that 'order by xxx desc limit 7' has been suggested in other answers but it doesn't seem to work well in this scenario. Would greatly appreciate any help, thanks!
Heres my code:
$result = mysqli_query($conn, "SELECT count(*) FROM test_table WHERE sleep = 1");
$row = mysqli_fetch_row($result);
$num = $row[0];
You can try this one:
SELECT a, COUNT(b) FROM test_table
WHERE sleep = 1
GROUP BY a
ORDER BY COUNT(b) ASC
LIMIT 7
Here, a is the name of your column you are trying to count
And, b is any column name for usage to count (it can id, or any column name)
If the sleep is binary/tinyint you can just sum that in the query with the order by.
SELECT sum(sleep)
FROM table
ORDER BY COUNT(id) DESC
LIMIT 7
If sleep isn't binary you can use a case statement.
SELECT sum(case when sleep = 1 then 1 else 0 end) as totalsleep
FROM table
ORDER BY COUNT(id) DESC
LIMIT 7
Here's my idea, get all the data in test_table and create a loop that will count the sleep, like this
$result = mysqli_query($link, "SELECT sleep FROM test_table;");
$x=1;
$sleep = [];
$SleepCount= 0;
while($row = mysqli_fetch_array($result)) {
if($row[0] == "1"){
$SleepCount++;
}
if($x == 7){
array_push($sleep,$SleepCount);
$SleepCount = 0;
$x=0;
}
$x++;
}
echo "<pre>",print_r($sleep),"</pre>";

PHP / SQL: Update Table C if meet condition after updated in Table A and Table B

I got some issues with my current code. Example, on a PHP page, there's a table that displays all tools that borrowed the users. In that table, each data rows contain a checkbox. Users can select any tools that they want to return first by tick the checkbox and press "return" button.
At Server-side, after clicking the "return" button, it will go to the page named return_selected.php. At this page, it will update Table A and Table B. This one is successful.
Now, I want to update Table C if all there's a condition, for example, ALL tools returned. This one I still do but failed. Below is the code
return_selected.php
<?php
include("../../../../config/configPDO.php");
include("../../../../config/check.php");
$tools_id = $_POST['tools_id'];
$borrow_id = $_POST['borrow_id'];
$checkbox=explode( ',', $_POST['ids'][0] );
for($i=0;$i < count($checkbox); $i++){
$tools_id=$checkbox[$i];
$sql="UPDATE ets_tools SET borrow_id = NULL WHERE tools_id=:tools_id";
$query=$conn->prepare($sql);
$query->execute(array(':tools_id' => $tools_id));
$sql2="UPDATE ets_tools_borrow SET time_to = GETDATE() WHERE tools_id=:tools_id";
$query3=$conn->prepare($sql2);
$query3->execute(array(':tools_id' => $tools_id));
// want to update table if all tools returned.
$query2 = "
SELECT
ets_tools.tools_id, ets_tools.tools_name, ets_tools.borrow_id,
ets_borrow.time_from, ets_borrow.time_to, ets_borrow.status_id
FROM ets_tools
INNER JOIN ets_borrow ON ets_tools.borrow_id = ets_borrow.borrow_id
WHERE ets_tools.borrow_id IS NOT NULL AND ets_borrow.borrow_id = :borrow_id
";
$sql2=$conn->prepare($query2);
$sql2->execute(array(':borrow_id' => $borrow_id));
if($sql2->rowCount() > 0)
{
header("Location: return.php");
}else{
$sql3="UPDATE ets_borrow SET time_to = GETDATE(), status_id = 2 WHERE borrow_id=:borrow_id";
$query3=$conn->prepare($sql3);
$query3->execute(array(':borrow_id' => $borrow_id));
header("Location: return.php");
}
}
?>
Can anyone know how to solve this? Thank you.
You need to consider the following:
As is mentioned in the documentation, PDOStatement::rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement executed by the corresponding PDOStatement object and for most databases the number of rows returned from a SELECT statement is not returned correctly. So, you may use a SELECT COUNT(*) ... approach to get this count.
For your specific case you may try to use an UPDATE ... WHERE NOT EXISTS ... statement to update the rows in the ets_borrow table and skip this SELECT ... FROM ... INNER JOIN ... statement.
I'm not sure if I understand corectly the use of header("Location: return.php"); in a for loop, probably you need to redirect after this loop.
Example, based on your code:
<?php
include("../../../../config/configPDO.php");
include("../../../../config/check.php");
$tools_id = $_POST['tools_id'];
$borrow_id = $_POST['borrow_id'];
$checkbox=explode( ',', $_POST['ids'][0] );
for($i=0; $i < count($checkbox); $i++) {
$tools_id=$checkbox[$i];
$sql = "UPDATE ets_tools SET borrow_id = NULL WHERE tools_id = :tools_id";
$query = $conn->prepare($sql);
$query->execute(array(':tools_id' => $tools_id));
$sql2 = "UPDATE ets_tools_borrow SET time_to = GETDATE() WHERE tools_id = :tools_id";
$query2 = $conn->prepare($sql2);
$query2->execute(array(':tools_id' => $tools_id));
$sql3 = "
UPDATE ets_borrow
SET time_to = GETDATE(), status_id = 2
WHERE
(borrow_id = :borrow_id1) AND
NOT EXISTS (
SELECT 1
FROM ets_tools
INNER JOIN ets_borrow ON ets_tools.borrow_id = ets_borrow.borrow_id
WHERE ets_tools.borrow_id IS NOT NULL AND ets_borrow.borrow_id = :borrow_id2
)
";
$borrow_id1 = $borrow_id;
$borrow_id2 = $borrow_id;
$query3 = $conn->prepare($sql3);
$query3->execute(array(':borrow_id1' => $borrow_id1, ':borrow_id2' => $borrow_id2));
}
header("Location: return.php");
?>

PHP optimize multiple update and select query

I have a php API where i am checking different conditions and based on that, i am fetching the count of the row and updating the count in the same table.
Below are the Conditions i am writing the query: (Note: 1 user can have multiple campaigns)
1) For a given user(Uid), for a particular campaign whose type = Impression, i am getting the Impression count and updating the same in table
2) For a given user(Uid), for a particular campaign whose type = Action i am getting the Action count and updating the same in table
//To get the Impression/Action/Lead count
$Impressionarr = [];
$Actionarr = [];
//IMPRESSION COUNT
$imp_qry = "select count(*) as ImpressionCount from ClicksAndImpressions where Uid = 101642 and CampaignID =100 and Type='Impression' ;";
$impData = $this->getClicksAndImpressionsTable()->CustomQuery($imp_qry);
if($impData[0]['ImpressionCount'] != '' || $impData[0]['ImpressionCount'] !=NULL ){
$impr_update = "UPDATE ClicksAndImpressions SET ImpressionCount = ". $impData[0]['ImpressionCount'] ." where Uid = 101642 and CampaignID =100 ;";
}else{
echo '----not Present';
}
//Impression count
foreach($impData as $key=>$data)
{
$data['ImpressionCount'];
$Impressionarr[] = $data;
}
//ACTION COUNT
$action_qry = "select count(*) as ActionCount from ClicksAndImpressions where Uid = 101617 and CampaignID =81 and Type = 'Action';";
$actionData = $this->getClicksAndImpressionsTable()->CustomQuery($action_qry);
if($actionData[0]['ActionCount'] != '' || $actionData[0]['ActionCount'] !=NULL ){
$action_update = "UPDATE ClicksAndImpressions SET ActionCount = ". $actionData[0]['ActionCount'] ." where Uid = 101617 and CampaignID =81 ;";
$actionData = $this->getClicksAndImpressionsTable()->CustomUpdate($action_update); //print_r($actionData);exit;
}else{
echo '----not Present';
}
//Action count
foreach($actionData as $key=>$data)
{
$data['ActionCount'];
$Actionarr[] = $data;
}
//Trying to combine the 3 arrays- but 2nd and 3rd not merging into 1st
$combine = array_merge($CampaignDetailsarr,$Impressionarr,$Actionarr);
1) Can the above duplicates - either in Update query or multiple for loops be avoided. if so how to optimize the above as per my conditions
ie) For
if( Uid = 123 for some campaignId = 11 and if type is 'Impression')
-> Update query for impression
else if(Uid = 123 for campaignId= 22 and if type = 'something else')
-> Update query for something else
2) I already have one array 1. I need to merge my 2 new arrays (Impressionarr[], Actionarr[]) into the 1st one, but below is how im getting.
Expected:
Coming as:
You could probably speed it up by creating a stored procedure in your database and calling that with the required data. From what I can see, most of the logic you have to do can be done in the stored procedure.

How to write sql query in php with if statement in WHERE

How do I write a SQL query with an if statement in the WHERE part of a query?
Here is my sql:
$sql = 'SELECT First, Second,
Third,Fifth, Status, Isik_id, Comments, Code
FROM Persons WHERE Status = 1 && Third = "'.$whoislogged.'" ORDER BY RAND() LIMIT 1';
The Third = "'.$whoislogged.'" is a word what comes from session.
If $whoislogged exists and is equal to Third then the query should be like:
$sql = 'SELECT First, Second, Third,Fifth, Status, Isik_id, Comments, Code
FROM Persons
WHERE Status = 1 && Third = "'.$whoislogged.'" ORDER BY RAND() LIMIT 1';
But if the $whoislogged dosent appear then the query should be like:
$sql = 'SELECT First, Second,
Third,Fifth, Status, Isik_id, Comments, Code
FROM Persons WHERE Status = 1 ORDER BY RAND() LIMIT 1';
So how can I put all this into one query?
You can handle it in query itself.
WHERE Status = 1 and if(Third = "'.$whoislogged.'", Third = "'.$whoislogged.'" , 1=1)
the condition part will check third is match with $whoislogged if it's true then add id as condition otherwise omit this condition.
Simply make a new variable that contains the Third statement
if ( !empty($whoislogged) ) $third = "AND Third = ". $whoislogged;
else $third = "";
$sql = 'SELECT First, Second,
Third,Fifth, Status, Isik_id, Comments, Code
FROM Persons WHERE Status = 1 '. $third .' ORDER BY RAND() LIMIT 1';
It is not the most efficient way but it works

creating an array of affected rows and processing them each in another query

Overview:
I can't figure out how to create an array of affected rows from a query and process each of them in another query.
Details:
My first query marks any account that hasn't been signed into in the past 90 days inactive. In the table phpbb_users there's a column user_id. For any affected rows by this first query I would like I would like an array containing the user_id's.
// first query
$result = mysql_query("UPDATE phpbb_users SET user_type = '1', user_inactive_time = '$inactivetime', theinactivereason = '90dayssincelastlogin', user_inactive_reason = '3' WHERE DATE_ADD(FROM_UNIXTIME(user_lastvisit), INTERVAL 90 DAY) < NOW() AND user_type = '0' AND user_lastvisit != '0'")
or die(mysql_error());
I would then like to process each userid in the array from the first query through the second query and SET activenumber = '0' in the table phpbb_phonelist.
// second query -> $user_id is the column user_id corresponding to each row in the first query
$result = mysql_query("UPDATE phpbb_phonelist SET activenumber = '0' WHERE whoid = '$user_id'")
or die(mysql_error());
It would be inefficient to loop through all the users, so I will show you the recommended way.
You can have a single SQL statement like this (Please test on a DB copy first):
$result =
mysql_query("UPDATE phpbb_users, phpbb_phonelist
SET
phpbb_users.user_type = '1',
phpbb_users.user_inactive_time = '$inactivetime',
phpbb_users.theinactivereason = '90dayssincelastlogin',
phpbb_users.user_inactive_reason = '3',
phpbb_phonelist.activenumber = '0'
WHERE
DATE_ADD(FROM_UNIXTIME(phpbb_users.user_lastvisit), INTERVAL 90 DAY) < NOW()
AND phpbb_users.user_type = '0'
AND phpbb_users.user_lastvisit != '0'
AND phpbb_phonelist.whoid = phpbb_users.user_id ");
Not sure what your users ID column is.

Categories