Records retrieved twice - php

I have the following php/mySQL code:
$wp_sql_query_text = "SELECT table1.field1, table1.field2, table1.field3,
table2.field1, table2.field2,table3.field1, table3.field2 from table1
INNER JOIN table2 ON table1.field2=table2.field1
INNER JOIN table3 ON table1.field3=table3.field1
WHERE table1.field1 > SOME_VALUE
ORDER BY table1field1";
echo $wp_sql_query_text;
$get_app_history = mysqli_query($conn,$wp_sql_query_text);
$app_entry = mysqli_fetch_assoc($get_app_history);
//some additional code for initialization of counters and variables
while ($app_entry = mysqli_fetch_assoc($get_app_history)){
//some processing
}
Simply put
1) There are 3 tables - table1, table2 and table3.
2) table1 has 3 fields - field1, field2 and field3.
3) table2 and table3 have 2 fields
each.
After 'echo'ing the sql query, I cut and pasted the sql in my phpmyadmin and records are retrieved only once.
However, on my page, I get the same record retrieved twice.

This is because you are fetching your result twice
$app_entry = mysqli_fetch_assoc($get_app_history); // first fetch
.......some additional code for initialization of kounters and variables.....
while ($app_entry = mysqli_fetch_assoc($get_app_history)) // second fetch with a loop
I would suggest to remove first and keep the loop that you might use in case of multiple results

Related

Using Multiple WHERE clause in an INSERT INTO ... SELECT statement

Am having two tables inside my Database lets say Table1 and Table2, and am trying to copy the values from a specific rows(fields) in Table2 to a specific single row on Table1, The specific rows to be moved are determined by the User Input of Particular UserID of each row from Table1.
Table Structure:
Table 1: a_uid,a_FName,a_Username,a_PhoneNo,b_uid,b_FName,b_Username,b_PhoneNo......
And Table 2 Structure:
Table 2: uid,FName,Username,PhoneNo.....
Am uing the INSERT INTO .. SELECT statement, but with multiple WHERE clause but its giving me erros
INSERT INTO table1 WHERE uid='userinput1' (b_FName,b_Username,b_PhoneNo,) SELECT FName,Username,PhoneNo FROM table2 WHERE uid='userinput2';
But am getting Error
This type of clause was previously parsed. (near WHERE)
If the row in table1 already exists, you need an UPDATE .. JOIN statement instead of INSERT .. SELECT.
UPDATE table1 t1
JOIN table2 t2 ON t2.uid='userinput2'
SET t1.b_FName = t2.FName,
t1.b_Username = t2.Username,
t1.b_PhoneNo = t2.PhoneNo
WHERE t1.uid='userinput1'
If you don't know if the row in table1 already exists, you can use an INSERT .. SELECT .. ON DUPLICATE KEY UPDATE statement:
INSERT INTO table1 (uid, b_FName, b_Username, b_PhoneNo)
SELECT 'userinput1', FName, Username, PhoneNo
FROM table2
WHERE uid = 'userinput2'
ON DUPLICATE KEY UPDATE
SET b_FName = VALUES(FName),
b_Username = VALUES(Username),
b_PhoneNo = VALUES(PhoneNo)
Note that uid sould be primary keys or at least unique in both tables.
For sql-server it would be something like this:
INSERT INTO table1 (uid,FName,Username,PhoneNo)
SELECT #userinput1, FName,Username,PhoneNo
FROM table2
WHERE table2.uid=#userinput2;

How can I dynamically select a limited number of items using 2 MySQL queries?

On the homepage of my web application I will be displaying a limited number of items. I have 2 queries from 2 different tables in order to display these particular items:
'table1' contains a list of all the items for my application
'table2' contains a column which is used as a reference id to certain items with the same id from 'table1'
This allows me to select which items to display on the homepage.
I have 2 queries:
$t1_items = DB::fetch("SELECT * FROM 'table1'");
$t2_items = DB::fetch("SELECT * FROM 'table2'");
I have 2 foreach loops that run through each table, and compares the id from 'table2' with each item in the 'table1'. If the ids from both tables match, it displays the item on the homepage.
This allows me to select the items I want to display on the homepage by changing the reference id for each item in 'table2'.
Here's my code for the foreach loops:
<?php
foreach ($t1_items as $i => $t1_item) {
foreach ($t2_items as $i => $t2_item) {
if ($t1_item->id == $t2_item->ref_id) {
echo $t1_item->title;
}
}
}
?>
Here's the table structure:
table1: position_name - ref_id
table2: id - title
This code works perfectly fine, the only problem is that it's obviously extremely inefficient since it has to scan through every single item in my database tables in order to grab only a few select items.
Is there a way that I can make $t1_items only dynamically query the items which have the same id the same as each reference id from $t2_items? I need something that is optimised, fast and lightweight in order to support heavy traffic.
Thanks for the help! :)
Have you tried to join the tables into one query?
ie:
select
t1.*
from table1 t1 inner join
table2 t2 on t1.id = t2.ref_id
that will return all rows from table1 that have a row with ref_id=id in table2.
Why not use a subquery in your first query to only pull in items that exist in table2?
$t1_items = DB::fetch("SELECT * FROM 'table1' as t1 WHERE EXISTS (SELECT * FROM 'table2' as t2 WHERE t1.id = t2.ref_id)");
This way you accomplish everything in a single query and let the database do the work.
use following code to get all records from table1 which are also in table2 table as foreign key ref_id
$items = DB::fetch("SELECT * FROM `table1` t1 LEFT JOIN `table2` t2 ON `t2`.ref_id = `t2`.id");
Now, use following loop to loop over all records
<?php
foreach ($items as $i => $item) {
// Displays the item
}
?>

disable unique sql row result constraint

I'm looping through a table, quests, storing the NPC ids per that Quest, then looping through table NPCs, and returning all NPC data per NPC id.
The values boxed in red should be returning.
Table: quests
Table: npcs
I'm looping through all received NPC_ids from quests table, and dump array to make sure it's not missing any data. No data missing.
var_dump($allNPCIDs); //all 5 results
Then dump the query to make sure imploded string isn't missing any data. No data missing.
var_dump($qry); //query shows all 5 results
Issue:
But when I dump the $row, I'm missing the duplicate npd_id:
var_dump($row); //missing 1 row, the duplicate npc_id
PHP:
foreach ($allNPCIDsPerQuest as $item) {
foreach ($item as $value) {
array_push($allNPCIDs, $value);
}
}
echo "DUMPING ARRAY";
var_dump($allNPCIDs);
//load NPC data
$qry =
'SELECT N.*
FROM npcs N
WHERE npc_id IN ("' . implode('", "', $allNPCIDs) . '")';
echo "DUMPING QRY STRING";
var_dump($qry);
$result = $mysqli->query($qry) or die(mysqli_error($mysqli));
$i = 0;
echo "DUMPING ROW DATA";
while ($row = $result->fetch_assoc()) {
var_dump($row);
$i++;
}
How do I turn off constraints for deleting duplicate row data in phpMyAdmin mySQL DB?
It's a not a constraint you can turn off. It's the structure of the query you are executing. Using an IN (1,2,3,4,1) is the same as using an IN (1,2,3,4). It is just a condition to filter the npcs table and decide if a particular row is to be selected or not. Having the id listed twice does not make the row exist twice in the npcs table... so it cannot be selected twice.
What you want cannot be done with that SELECT.
You either use a UNION:
(SELECT * FROM npcs WHERE npc_id=1) UNION
(SELECT * FROM npcs WHERE npc_id=2) UNION
(SELECT * FROM npcs WHERE npc_id=3) UNION
(SELECT * FROM npcs WHERE npc_id=4) UNION
(SELECT * FROM npcs WHERE npc_id=1)
or you first insert the ids in a temp table and then SELECT like this:
SELECT N.* FROM npcs N JOIN temptable T on N.npc_id=T.npc_id
or you do it client side, with a loop, executing a query for each ID and putting the data together.
There may be other solutions, but they don't come to mind right now.
This is no constraint in phpMyAdmin, but how SQL works.
SELECT N.* FROM npcs N would return 5 rows (npc_id 1 to 5). WHERE limits this to rows that match your conditions. You don't get extra rows if you repeat conditions.
You could extract the column npc_id from table quests into a lookup table quests_to_npcs with the columns quest_id and npc_id. This would contain a row for each npc in a quest.
Your query might look like this:
SELECT n.*
FROM quests AS q
INNER JOIN quests_to_npcs AS q2n ON q.quest_id = q2n.quest_id
INNER JOIN npcs AS n ON q2n.npc_id = n.npc_id
You should create another table called something like quest_npcs.
CREATE TABLE quest_npcs (
quest_id INT,
npc_id INT
);
Then you can simply store all the associated npc_ids for each quest on a row each.
To then pull the information for all the NPCs for a particular quest it's a straightforward join.
SELECT npcs.*
FROM quest_npcs
INNER JOIN npcs
ON npcs.npc_id = quest_npcs.npc_id
WHERE quest_npcs.quest_id = ???
You can even join the quest table into that if you want to get information on the quest in the same query.
SELECT npcs.*, quests.*
FROM quests
INNER JOIN quest_npcs
ON quest_npcs.quest_id = quests.quest_id
INNER JOIN npcs
ON npcs.npc_id = quest_npcs.npc_id
WHERE quest_npcs.quest_id = ???
Or in your case, instead of WHERE quest_npcs.quest_id = ???, use IN() on the quest_id to get a bunch of quests all at once.
SELECT npcs.*, quests.*
FROM quests
INNER JOIN quest_npcs
ON quest_npcs.quest_id = quests.quest_id
INNER JOIN npcs
ON npcs.npc_id = quest_npcs.npc_id
WHERE quest_npcs.quest_id IN(???)

remove identical values from 2 mysqli queries

I want to make 2 mysqli queries. But if there are values in the second query that are Identical to the values yielded from the first query I want to exclude those values from the result set. What I have now only seems to work for 1 identical value. the rest of the identical values are shown. how should I change this? Thanks.
$query1 = $db->query("SELECT colTab1 FROM table1");
while ($result1 = $query1 ->fetch_assoc()) {
$query2 = $db->query("SELECT colTab2 FROM table2 WHERE colTab2 <> $result1[colTab1]");
echo $result1['colTab1']."<br>";
}
while ($result2 = $query2 ->fetch_assoc()) {
echo $result2['colTab2']."<br>";
}
}
Well, you can modify your second query as follows:
SELECT colTab2 FROM table2 WHERE colTab2 NOT IN (SELECT colTab1 FROM table1)
Or maybe you just want to select the UNION of the two tables (which will omit duplicates by default):
SELECT colTab1 FROM table1
UNION
SELECT colTab2 FROM table2
(Note that relying on UNION to omit duplicates between the two recordsets is not quite the same thing, as any duplicates that exist within each recordset will also be omitted; if that is a concern, one can SELECT DISTINCT ... UNION ALL SELECT DISTINCT ... instead).
Just run one query; why bring back data from the database to filter on? Filter in the DB.
SELECT colTab2
FROM table2
WHERE colTab2 NOT IN (
SELECT colTab1
FROM table1
)

How can I update multiple mysql columns of a row using the result of a select query?

I have a reviews table that contains three ways to rate an item. The items themselves then have three columns to hold the average for each value respectively.
I could do this using three nested queries in an update query, but I feel like this is inefficient... Is there a way to update them all at once?
So far I've used this as my select query:
SELECT AVG(rating_1),AVG(rating_2),AVG(rating_3) FROM items_reviews WHERE item_id = 1
I just don't know how to use the result of that query to update an item row.
You could use an join in the UPDATE:
UPDATE items a
INNER JOIN
(
SELECT
item_id,
AVG(rating_1) AS avg1,
AVG(rating_2) AS avg2,
AVG(rating_3) AS avg3
FROM items_reviews
WHERE item_id = 1
GROUP BY item_id
) b ON a.item_id = b.item_id
SET
a.avgrating1 = b.avg1,
a.avgrating2 = b.avg2,
a.avgrating3 = b.avg3

Categories