I want to delete some posts in a database, but for some rows, only if they are the only children with the same id in it's table. Is it possible to do all of the below in one single query, instead of selecting the data and making loops and ifs?
Basically I want to delete from sessions only if there is 1 hit in session_projects and delete from rec_projects only if there is 1 hit in sessions and all of the hits in session_projects
Is this possible? (please don't mind the unprepared statements in this case)
$pid = 1; // varies
$sql = "SELECT ss_id, rp_id
FROM session_projects
INNER JOIN sessions
ON ss_id = sp_ss_id
INNER JOIN rec_projects
ON rp_id = ss_rp_id
WHERE sp_p_id = $pid";
$session_projects = mysqli_query($db_link, $sql);
while( $row = mysqli_fetch_array($session_projects) )
{
$sql = "SELECT COUNT(*) as session_projects_count FROM session_projects WHERE sp_ss_id = " . $row['ss_id'];
$result = mysqli_query($db_link, $sql);
$session_projects_count = mysqli_fetch_assoc($result);
if( $session_projects_count['session_projects_count'] == 1 )
{
$sql = "SELECT COUNT(*) as sessions_count FROM sessions WHERE ss_rp_id = " . $row['rp_id'];
$result = mysqli_query($db_link, $sql);
$sessions_count = mysqli_fetch_assoc($result);
$sql = "DELETE FROM sessions
WHERE ss_id = " . $row['ss_id'];
$delete_sessions = mysqli_query($db_link, $sql);
if( $sessions_count['sessions_count'] == 1 )
{
$sql = "DELETE FROM rec_projects
WHERE rp_id = " . $row['rp_id'];
$delete_rec_projects = mysqli_query($db_link, $sql);
}
}
}
$sql = "DELETE FROM session_projects
WHERE sp_p_id = $pid";
$delete_session_projects = mysqli_query($db_link, $sql);
You could always aggregate into arrays and delete with IN (), that way you'd have one delete query per table:
// ...
$delSsId = array();
$delRpId = array();
while( $row = mysqli_fetch_array($session_projects) )
{
// ...
if( $session_projects_count['session_projects_count'] == 1 )
{
// ...
$delSsId[] = $row['ss_id'];
if( $sessions_count['sessions_count'] == 1 )
$delRpId[] = $row['rp_id'];
}
}
$sql = "DELETE FROM sessions
WHERE ss_id IN (" . implode(",", $delSsId) . ")";
$delete_sessions = mysqli_query($db_link, $sql);
$sql = "DELETE FROM rec_projects
WHERE rp_id IN (" . implode(",", $delRpId) . ")";
$delete_rec_projects = mysqli_query($db_link, $sql);
The same principle can be applied to your select queries inside the loop; select all rows that could apply into arrays and then use the data from there.
However this could be a bad idea if you have enormously large tables as you might end up loading thousands of rows into arrays, wasting time and memory.
From my personal experience there isn't much performance benefit in optimizing the amount of reading (SELECT) queries anyways, it's usually writing (INSERT, UPDATE, DELETE, ...) queries that have the biggest impact.
Related
I am running a line graph on RGraph framework, and I am using a SELECT COUNT statement for rejected, accepted, approved etc.....counting how many items was rejected or accepted etc and then dumping the query data into an array, However I am looking for an easier way to implement this query, instead of running a query on each unique row value, also thinking in the way if I have to encounter other column data besides rejected, accepted or etc....I wouldnt, my code doesnt seem very scalable then. Please help
So far, I am running a query for each keyword, hope my code explains this.
The final variable is what i am feeding to RGRAPH, This works fine as it is, however it isn't the right way, and not very scalable, should my row data change.
<?php
$cxn = mysqli_connect("localhost","root","", "csvimport");
$query = "SELECT COUNT(*) FROM table_1 WHERE conclusion = 'rejected'";
$result = mysqli_query($cxn, $query) or die(mysqli_error($cxn));
$display = mysqli_fetch_array($result);
$rejected = $display[0];
//echo $rejected;
$query = "SELECT COUNT(*) FROM table_1 WHERE conclusion =
'accepted'";
$result = mysqli_query($cxn, $query) or die(mysqli_error($cxn));
$display = mysqli_fetch_array($result);
$accepted = $display[0];
//echo $accepted;
$query = "SELECT COUNT(*) FROM table_1 WHERE conclusion = '-'";
$result = mysqli_query($cxn, $query) or die(mysqli_error($cxn));
$display = mysqli_fetch_array($result);
$dash = $display[0];
//echo $dash;
$query = "SELECT COUNT(*) FROM table_1 WHERE conclusion =
'approved'";
$result = mysqli_query($cxn, $query) or die(mysqli_error($cxn));
$display = mysqli_fetch_array($result);
$approved = $display[0];
//echo $approved;
$datarray = [$rejected, $accepted, $dash, $approved];
print_r($datarray);
$data_string = "[" . join(", ", $datarray) . "]";
echo "<br>";
print_r($data_string);
?>
You can just use GROUP BY and add the conclusion column to the result set, so
SELECT conclusion, COUNT(*) as total
FROM table_1
WHERE conclusion in ('rejected', 'accepted', '-', 'approved')
GROUP BY conclusion
Then retrieve each row of the result set
$totals = [];
while($row = mysqli_fetch_array($result)) {
$totals [$row[0]] = [$row[1]];
}
and $totals will be an array something like
array( 'accepted' => 12,
'approved' => 20...)
If you want all of the conclusions, then just remove the WHERE conclusion in line and it will return all of the possibilities along with the count.
I have that simple php code:
$sql= 'SELECT ID, fb_postid, scheduled FROM `posts` WHERE clicks = "" AND fb_postid !="" AND scheduled < NOW() order by ID ASC LIMIT 10;';
$result = mysqli_query($link, $sql);
print_r($result);
while ($row = mysqli_fetch_assoc($result)) {
$clicks=fbcall($fbtoken, $row['fb_postid']);
$update="UPDATE `posts` SET `clicks`='".$clicks."' WHERE id='".$row['ID']."'";
$result = mysqli_query($link, $update);
print("POSTID: " . $row['fb_postid'] . " - Clicks: " . $clicks ."<br>");
};
The MYSQL SELECT gets 10 Lines from DB loops through the line in the While Loop, gets "clicks" from function fbcall and then should update all 10 lines with the values from "clicks" to the db. if i run the code without update i get 10 results printed but if i run with mysqli_update i just get 1 row updated. Anybody any Idea why?
You're using the $result variable to iterate through a list of rows from the first query.
But you're giving $result a new value within the loop, clearing whatever was there.
Just use two different variables, and you'll be fine. Try something like this:
$sql= 'SELECT ID, fb_postid, scheduled FROM `posts` WHERE clicks = "" AND fb_postid !="" AND scheduled < NOW() order by ID ASC LIMIT 10;';
$result = mysqli_query($link, $sql);
print_r($result);
while ($row = mysqli_fetch_assoc($result)) {
$clicks=fbcall($fbtoken, $row['fb_postid']);
$update="UPDATE `posts` SET `clicks`='".$clicks."' WHERE id='".$row['ID']."'";
$result2 = mysqli_query($link, $update);
print("POSTID: " . $row['fb_postid'] . " - Clicks: " . $clicks ."<br>");
};
Fixed it and built with prepared update statement:
$sql= 'SELECT ID, fb_postid, scheduled FROM `posts` WHERE clicks = "" AND fb_postid !="" AND scheduled < NOW() order by ID ASC LIMIT 10;';
$result = mysqli_query($link, $sql);
$qry = "UPDATE `posts` SET `clicks`=? WHERE id=?";
$stmt = mysqli_prepare ($link, $qry);
mysqli_stmt_bind_param ($stmt, 'ss',$clicks, $id);
while ($row = mysqli_fetch_assoc($result)) {
$clicks=fbcall($fbtoken, $row['fb_postid']);
$id=$row['ID'];
mysqli_stmt_execute($stmt);
print("POSTID: " . $row['fb_postid'] . " - Clicks: " . $clicks ."<br>");
};
Apologies if I have the terminology wrong.
I have a for loop in php which operates a mysql query...
for ($i = 0; $i <count($user_id_pc); $i++)
{
$query2 = " SELECT job_title, job_info FROM job_description WHERE postcode_ss = '$user_id_pc[$i]'";
$job_data = mysqli_query($dbc, $query2);
$job_results = array();
while ($row = mysqli_fetch_array($job_data))
{
array_push($job_results, $row);
}
}
The results that are given when I insert a...
print_r ($job_results);
On screen -> Array()
If I change the query from $user_id_pc[$i] to $user_id_pc[14] for example I receive one set of results.
If I include this code after the query and inside the for loop
echo $i;
echo $user_id_pc[$i] . "<br>";
I receive the number the counter $i is on followed by the data inside the array for that counter position.
I am not sure why the array $job_results is empty from the query using the counter $i but not if I enter the number manually?
Is it a special character I need to escape?
The full code
<?php
print_r ($user_id_pc);
//Select all columns to see if user has a profile
$query = "SELECT * FROM user_profile WHERE user_id = '" . $_SESSION['user_id'] . "'";
//If the user has an empty profile direct them to the home page
$data = mysqli_query($dbc, $query);
if (mysqli_num_rows($data) == 0)
{
echo '<br><div class="alert alert-warning" role="alert"><h3>Your appear not to be logged on please visit the home page to log on or register. <em>Thank you.</em></h3></div>';
}
//Select data from user and asign them to variables
else
{
$data = mysqli_query($dbc, $query);
if (mysqli_num_rows($data) == 1)
{
$row = mysqli_fetch_array($data);
$cw_job_name = $row['job_description'];
$cw_rate = $row['hourly_rate'];
$job_mileage = $row['mileage'];
$job_postcode = $row['postcode'];
$response_id = $row['user_profile_id'];
}
}
for ($i = 0; $i <count($user_id_pc); $i++)
{
$query2 = " SELECT job_title, job_info FROM job_description WHERE postcode_ss = '{$user_id_pc[$i]}'";
$job_data = mysqli_query($dbc, $query2);
$job_results = array();
while ($row = mysqli_fetch_array($job_data))
{
array_push($job_results, $row);
}
echo $i;
?>
<br>
<?php
}
print ($query2);
print $user_id_pc[$i];
?>
This is primarily a syntax error, the correct syntax should be:
$query2 = " SELECT job_title, job_info FROM job_description WHERE postcode_ss = '{$user_id_pc[$i]}'";
Note that this is correct syntax but still wrong!! For two reasons the first is that it's almost always better (faster, more efficient, takes less resources) to do a join or a subquery or a simple IN(array) type query rather than to loop and query multiple times.
The second issue is that passing parameters in this manner leave your vulnerable to sql injection. You should use prepared statements.
The correct way
if(count($user_id_pc)) {
$stmt = mysqli_stmt_prepare(" SELECT job_title, job_info FROM job_description WHERE postcode_ss = ?");
mysqli_stmt_bind_param($stmt, "s", "'" . implode("','",$user_id_pc) . "'");
mysqli_stmt_execute($stmt);
}
Note that the for loop has been replaced by a simple if
You have to check the query variable, instead of:
$query2 = " SELECT job_title, job_info FROM job_description WHERE postcode_ss = '$user_id_pc[$i]'"
have you tried this:
$query2 = " SELECT job_title, job_info FROM job_description WHERE postcode_ss = '" . $user_id_pc[$i] . "' ";
And another thing, try something different like this:
while ($row = mysqli_fetch_array($job_data))
{
$job_results[] = array("job_title" => $row["job_title"], "job_info" => $row["job_info");
}
Then try to print the values.
Sorry but I like foreach(), so your working code is:
<?php
// To store the result
$job_results = [];
foreach($user_id_pc as $id ){
// selecting matching rows
$query2 ="SELECT job_title, job_info FROM job_description WHERE postcode_ss = '".$id."'";
$job_data = mysqli_query($dbc, $query2);
// checking if query fetch any result
if(mysqli_num_rows($job_data)){
// fetching the result
while ($row = mysqli_fetch_array($job_data)){
// storing resulting row
$job_results[] = $row;
}
}
}
// to print the result
var_dump($job_results);
Hi there Im still trying to change to mysqli, and I just can get things to go right some times.
The biggest thing I have is the mysqli_result, ive tried what other people have done, and doesnt seem to work.
Here is the code below:
$result = mysqli_query($con, "SELECT referer FROM users WHERE userId = '$key'");
if(mysql_result($result, 0) != "" ){
$referer = mysql_result($result, 0);
$result = mysqli_query($con, "SELECT referer FROM users WHERE userId = $referer'");
if(mysql_result($result, 0) != "" ){
$result2 = mysqli_query($con, "SELECT refered FROM users WHERE userId = $referer'");
$newRefs = mysql_result($result2, 0) + 1;
mysqli_query($con, "UPDATE users SET refered = '$newRefs' WHERE userId = '$referer'");
$result3 = mysqli_query($con, "SELECT userName FROM users WHERE userId = '$key'");
$refered = mysql_result($result3, 0);
}
}
Help would be appreciated.
Kind Regards
Chad
You can't mix mysql_ and mysqli_ functions like that. Also, mysql_result is serious old school. There is no equivalent in mysqli (and that's a good thing). I switched to mysqli_fetch_assoc, which takes your query and returns an associative array with the field names as keys. I kept it all procedural for the sake of uniformity (I hate mixing OOP with procedural). I should note that your code is horribly convoluted as written (for instance $key isn't defined anywhere). It's better to avoid reusing variable named like you have. I also HIGHLY recommend switching to an all-object codebase.
$result = mysqli_query($con, "SELECT referer FROM users WHERE userId = '$key'");
if($row = mysqli_fetch_assoc($result)){
$result2 = mysqli_query($con, "SELECT referer FROM users WHERE userId = '" . $row['referer'] . "'");
if($row2 = mysqli_fetch_assoc($result2)){
$result3 = mysqli_query($con, "SELECT refered FROM users WHERE userId = '" . $row2['referer'] . "'");
$newRefs = mysqli_fetch_assoc($result3);
mysqli_query($con, "UPDATE users SET refered = '" . $newRefs['refered'] . "' WHERE userId = '" . $row['referer'] . "'");
$result4 = mysqli_query($con, "SELECT userName FROM users WHERE userId = '$key'");
$refered = mysqli_fetch_assoc($result4);
}
}
You cannot use mysql_result!
Try to do it like this:
$result = mysqli_query($con, "SELECT referer FROM users WHERE userId = '$key'");
if( mysqli_num_rows($result, 0) ) {
list($referer) = mysqli_fetch_row($result);
....
You can use object oriented style:
$Result = $Con->query("SELECT referer FROM users WHERE userId = '$key'");
if( $Result->num_rows ) {
list($referer) = $Result->fetch_row();
If you're in the process of switching, you should go straight to PDO, not mysqli.
mysqli vs pdo - stackoverflow
<?php
$query1 = "CREATE VIEW current_rankings AS SELECT * FROM main_table WHERE date = X";
$query2 = "CREATE VIEW previous_rankings AS SELECT rank FROM main_table WHERE date = date_sub('X', INTERVAL 1 MONTH)";
$query3 = "CREATE VIEW final_output AS SELECT current_rankings.player, current_rankings.rank as current_rank LEFT JOIN previous_rankings.rank as prev_rank
ON (current_rankings.player = previous_rankings.player)";
$query4 = "SELECT *, #rank_change = prev_rank - current_rank as rank_change from final_output";
$result = mysql_query($query4) or die(mysql_error());
while($row = mysql_fetch_array($result)) {
echo $row['player']. $row['current_rank']. $row['prev_rank']. $row['rank_change'];
}
?>
All the queries work independently but am really struggling putting all the pieces together in one single result so I can use it with mysql_fetch_array.
I've tried to create views as well as temporary tables but each time it either says table does not exist or return an empty fetch array loop...logic is there but syntax is messed up I think as it's the 1st time I had to deal with multiple queries I need to merge all together. Looking forward to some support. Many thanks.
Thanks to php.net I've come up with a solution : you have to use (mysqli_multi_query($link, $query)) to run multiple concatenated queries.
/* create sql connection*/
$link = mysqli_connect("server", "user", "password", "database");
$query = "SQL STATEMENTS;"; /* first query : Notice the 2 semicolons at the end ! */
$query .= "SQL STATEMENTS;"; /* Notice the dot before = and the 2 semicolons at the end ! */
$query .= "SQL STATEMENTS;"; /* Notice the dot before = and the 2 semicolons at the end ! */
$query .= "SQL STATEMENTS"; /* last query : Notice the dot before = at the end ! */
/* Execute queries */
if (mysqli_multi_query($link, $query)) {
do {
/* store first result set */
if ($result = mysqli_store_result($link)) {
while ($row = mysqli_fetch_array($result))
/* print your results */
{
echo $row['column1'];
echo $row['column2'];
}
mysqli_free_result($result);
}
} while (mysqli_next_result($link));
}
EDIT - The solution above works if you really want to do one big query but it's also possible to execute as many queries as you wish and execute them separately.
$query1 = "Create temporary table A select c1 from t1";
$result1 = mysqli_query($link, $query1) or die(mysqli_error());
$query2 = "select c1 from A";
$result2 = mysqli_query($link, $query2) or die(mysqli_error());
while($row = mysqli_fetch_array($result2)) {
echo $row['c1'];
}
It seems you are not executing $query1 - $query3. You have just skipped to $query4 which won't work if the others have not been executed first.
Also
$query4 = "SELECT *, #rank_change = prev_rank - current_rank as rank_change from final_output";
should probably be
$query4 = "SELECT *, #rank_change := prev_rank - current_rank as rank_change from final_output";
or else the value of rank_change will just be a boolean, true if #rank_change is equal to (prev_rank - current_rank), false if it is not. But do you need #rank_change at all? Will you use it in a subsequent query? Maybe you can remove it altogether.
Even better, you could just combine all the queries into one like this:
SELECT
curr.player,
curr.rank AS current_rank,
#rank_change := prev.rank - curr.rank AS rank_change
FROM
main_table AS curr
LEFT JOIN main_table AS prev
ON curr.player = prev.player
WHERE
curr.date = X
AND prev.date = date_sub('X', INTERVAL 1 MONTH)
You should concatenate them:
<?php
$query = "CREATE VIEW current_rankings AS SELECT * FROM main_table WHERE date = X";
$query .= " CREATE VIEW previous_rankings AS SELECT rank FROM main_table WHERE date = date_sub('X', INTERVAL 1 MONTH)";
$query .= " CREATE VIEW final_output AS SELECT current_rankings.player, current_rankings.rank as current_rank LEFT JOIN previous_rankings.rank as prev_rank
ON (current_rankings.player = previous_rankings.player)";
$query .= " SELECT *, #rank_change = prev_rank - current_rank as rank_change from final_output";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result)) {
echo $row['player']. $row['current_rank']. $row['prev_rank']. $row['rank_change'];
}
?>