禁用唯一的sql行结果约束

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

enter image description here

Table: npcs

enter image description here

  • 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

enter image description here

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(???)