SQL returns 2 of the 3 rows - php

I'm trying to select something from a table and insert that information into another table
For example I've 3 rows in table A which I want to insert into table B, he only inserts 2 of the 3.
I got this: I've tried it with fetch_array() but I get only the error non-object
EDIT: THE PART OF THE SCRIPT
$log = $db->query("SELECT itemname FROM log_mitem WHERE mobname = '".$mobname."' AND game = '".$game."'") or die($db->error);
if($log1 = $log->fetch_object());
{
while($loco = $log->fetch_object())
{

You shouldn't have that first if, just do:
$log = $db->query("SELECT itemname FROM log_mitem WHERE mobname = '".$mobname."' AND game = '".$game."'") or die($db->error);
while($loco = $log->fetch_object()) {
// do something
}
Also note that you don't need a while loop for this trivial task, you can use INSERT INTO ... SELECT syntax
INSERT INTO table1 ( column1 )
SELECT col1
FROM table2
WHERE cond1

Related

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");
?>

Select from 2 tables not working with php mysql

I have two different tables of the following structure:
grouprel
id | userId | pupID | groupId
pupils
id | userId | fname | lname
pupId in groulrel is equal to id in pupils.
I want to fetch pupils from a different group and then order them by fname, lname.
Now I have two queries like this:
$q = "SELECT * FROM grouprel WHERE userid = ". $userid ." AND groupId = ". $_GET['id'] ."";
$r = mysqli_query($mysqli, $q);
while ($rows = mysqli_fetch_object($r)) {
$query = "SELECT id, fname, lname FROM pupils WHERE userid = ". $userid ." AND id = ". $rows->pupId ." AND status = 0 ORDER BY fname, lname";
$result = mysqli_query($mysqli, $query);
while($row = mysqli_fetch_object($result)) {
echo stuff...
}
}
This works, but it doesn't order the names alphabetically like I want to.
How could I fix this?
This is iterating over the first query:
while ($rows = mysqli_fetch_object($r)) {
And this iterates over each instance of the second query:
while($row = mysqli_fetch_object($result)) {
So if the first query returns 1,2,3, and each iteration of the second query returns A,B, then your output would be:
1 A
1 B
2 A
2 B
3 A
3 B
The second query is ordering by the ORDER BY clause you gave it. But you are ordering the entire output by the first query.
Ultimately, why do you need these separate queries at all? Executing a database query in a loop is almost always the wrong idea. It looks like all you need is one query with a simple JOIN. Guessing on your logic, something like this:
SELECT
pupils.id, pupils.fname, pupils.lname
FROM
pupils
INNER JOIN grouprel ON pupils.id = grouprel.pupId
WHERE
pupils.userid = ?
AND grouprel.groupId = ?
AND pupils.status = 0
ORDER BY
fname, lname
It may take a little tweaking to match exactly what you're looking for, but you can achieve your goal with a single query instead of multiple separate queries. Then the results of that query will be ordered the way you told MySQL to order them, instead of the way you told PHP to order them.

Query multiple totals at once in MYSQL PHP

I have a a table in my DB that has multiple columns with numbers I would like to query all the rows in 1 query with separate totals for all rows in each column in my db.
like so
$sql = '
SELECT sum(TOTAL1)
, sum(TOTAL2)
, sum(TOTAL3)
, sum(TOTAL4)
FROM TABLE WHERE ID = '.$ID.'';
it works when I do it with a single column query like this.
$sql = 'SELECT sum(TOTAL1) FROM TABLE WHERE ID = '.$ID.'';
but I can't seem to get it to work for multiples in 1 query does anyone know of a more proper way of doing this instead of in separate queries?
$sql = 'SELECT (sum(TOTAL1)+sum(TOTAL2)+sum(TOTAL3)+sum(TOTAL4)) AS FINALTOTAL FROM TABLE WHERE ID = '.$ID.'';
Use aliases.
Sidenote: Add your WHERE clause to the tested examples I've given below.
SELECT sum(TOTAL1) as total1, sum(TOTAL2) as total2
which if you want to use seperate aliases, is handy if you wish to echo them as different entities.
For example:
$query = mysqli_query($con, "SELECT SUM(col1) as total1,
SUM(col2) as total2,
SUM(col3) as total3 FROM table ");
while($row = mysqli_fetch_array($query)){
echo $row['total1']; // echo'd 125
echo "<br>";
echo $row['total2']; // echo'd 225
echo "<br>";
echo $row['total3']; // echo'd 2000
}
Sidenote: My three columns contained the following:
col1 in 2 rows 25, 100
col2 in 2 rows 25, 200
col3 in 2 rows 1000, 1000
To echo the total of all rows and for example: (and inside the while loop)
$total = $row['total1'] + $row['total2'] + $row['total3'];
echo $total;
Or in one go and as one alias and one row echo'd:
SELECT sum(TOTAL1 + TOTAL2 + TOTAL3) as total FROM table
I.e.:
$query = mysqli_query($con, "SELECT SUM(col1 + col2 + col3) as total FROM table ");
while($row = mysqli_fetch_array($query)){
echo $row['total'];
}
NOTE: DATA TYPE must be same for all fields which you want to SUM
By following query you can have SUM(field1)+SUM(field2)+ SUM(field3) .....n in 1 single field
I used this query for just 2 fields and both are integers
See this is my table definition
create table `siso_area_operativa` (
`id_area_operativa` int ,
`area_operativa` varchar (8),
`responsable` int
);
and this is query which you want
SELECT SUM(a.field1) FROM
(
SELECT
SUM(id_area_operativa) field1
FROM
siso_area_operativa
UNION ALL
SELECT SUM(responsable) field1
FROM
siso_area_operativa ) AS a
Result of this is
SUM(id_area_operativa) + SUM(responsable) in single field
ENJOY !!!!!!!!!!!!

SQL Query check column values if it's in an Array

My existing SQL Query:
$getEdu = "SELECT * FROM Request_Subject WHERE REQUEST_ID = $id
AND SUBJECT_ID IN (2,3,4)";
So in my Database, each REQUEST_ID can be associated with multiple SUBJECT_IDs
And SUBJECT_ID has values ranging from 1 to 10.
So my existing values in the table are:
REQUEST_ID: 1 -> SUBJECT_IDs: 2,3
REQUEST_ID: 2 -> SUBJECT_IDs: 2,4
REQUEST_ID: 3 -> SUBJECT_IDs: 2,8
So currently when the query runs, REQUEST_ID = 3 will still be included in the results because it has the SUBJECT_ID = 2.
Is there a possible way for me to create a SQL Query where even if one value matches, the Query would ignore the REQUEST_ID because it has different values from the array.
Thank you in advance.
UPDATE
Current Results:
$requestSubjects = array();
// So if I call REQUEST_ID = 3
$getEdu = "SELECT * FROM Request_Subject WHERE REQUEST_ID = 3
AND SUBJECT_ID IN (2,3,4)";
$getEdu_answer = mysqli_query($connection, $getEdu);
if(!$getEdu_answer || mysqli_num_rows($getEdu_answer)==0) {
echo "Error";
die();
}
else {
while($subjectRow = mysqli_fetch_assoc($getEdu_answer)) {
$subject = $subjectRow["Subject_ID"];
array_push($requestSubjects, $subject);
}
$reqSub = '{"reqSubject":' .json_encode($requestSubjects). '}';
echo $reqSub; // Returning a JSON to ajax
}
Echoed Results:
{"reqSubject":[2]}
The result is correct as the REQUEST_ID=3 is associated with a SUBJECT_ID = 2.
However what I want is that since REQUEST_ID=3 is also associated with SUBJECT_ID = 8, it should not echo a result at all.
If I understand you correctly, you have ALL SUBJECT_IDS of a REQUEST_ID to match (2,3,4) and only then to print the result?
if so, you can construct the query for each SUBJECT_ID
EDIT:
You must get ALL SUBJECT_IDs of REQUEST_ID using another sqlquery
Contact SUBJECT_IDs to your $getEdu query, and only then execute $getEdu query
Example:
$getEdu = "SELECT * FROM Request_Subject WHERE REQUEST_ID = $id";
//$sub_list is the all subect_id of $id
foreach ($sub_list as $sub_id){
$getEdu.=" AND $sub_id IN (2,3,4)";
}
$getEdu_answer = mysqli_query($connection, $getEdu);
If you execute it on your example, REQUEST_ID =3,
Than $qetEdu query should be:
SELECT * FROM Request_Subject WHERE REQUEST_ID = 3 AND 2 IN (2,3,4) AND 8 IN (2,3,4)
meaning that REQUEST_ID = 3 won't return because 8 is not in (2,3,4)
Hope it help a bit.
maybe
$getEdu = "SELECT * FROM Request_Subject WHERE REQUEST_ID=3
AND SUBJECT_ID IN (2,3,4, if(REQUEST_ID=3,8,null))";
if I understand you correctly...

MySQL/PHP query to reverse relationship

I have a mysql table with the following columns:
ID Units
1 1234,6543,9876
2 1234,6543
3 6543
4 9876
5 0987
I would like to reverse the relationship to get an output like this:
Unit IDs
1234 1,2
6543 1,2,3
9876 1,4
0987 5
I was wondering if this could be done in a query or some php, without chunking through with explodes etc?
Using comma-separated lists in SQL is awkward. This is a denormalized design, and SQL is not well suited to work with data in this format.
I would fetch all the data back into PHP and manipulate it there.
$id_per_unit = array();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$unit_array = explode(",", $row["Units"]);
foreach ($unit_array as $unit) {
$id_per_unit[$unit][] = $row["Id"];
}
}
Something like this:
$query = "SELECT `Unit`, `IDs` FROM `table` ORDER BY `Unit`";
$data = mysqli_query($con, $query);
$prev_unit = '';
while ($row = mysqli_fetch_array($data)) {
if ($prev_unit != $row['Unit']) {
// echo a new row with the new unit and then ID
} else {
// echo just the ID in the same row, this unit is the same as the last one.
}
$prev_unit = $row['Unit'];
}
With only SQL, you can do something like this :
SELECT unit , GROUP_CONCAT(id)
FROM (
SELECT id,substring_index(Units,',',1) AS unit
FROM Table1
UNION
SELECT id,REPLACE(
REPLACE(SUBSTRING_INDEX(Units,',',2),SUBSTRING_INDEX(Units,',',1),'')
,',','') AS unit
FROM Table1
UNION
SELECT id,REPLACE(
REPLACE(SUBSTRING_INDEX(Units,',',3),SUBSTRING_INDEX(Units,',',2),'')
,',','') AS unit
FROM Table1) AS UNITS
WHERE unit != ''
GROUP BY unit
See SQLFIDDLE

Categories