2011-09-12 2 views
1

Lorsqu'un cours (une ligne dans le tableau des conférences) est supprimé, il est déplacé dans le tableau 'lectures_deleted'. Cela agit comme une sorte de back-up. Dans ce cas, je dois être en mesure d'appeler à partir de ces deux tables, donc je voudrais obtenir les données de la table «conférences», mais si elle n'existe pas ici, je voudrais alors l'obtenir à la place de la table 'lectures_deleted'.Comment sélectionner un tableau quand il existe dans le tableau

Le code ci-dessous casse le site Web actuellement. Toute aide sera très appréciée!

function getModuleCode($id){ 
     $result = mysql_query(' 
      IF EXISTS 
       (SELECT * FROM lectures WHERE lecture_id="'.$id.'") 
      ELSE 
       SELECT * FROM lectures_deleted WHERE lecture_id="'.$id.'"; 
      ') 
     or die(mysql_error()); 
     $row = mysql_fetch_array($result); 
     return $row['module_code']; 
    } 
+0

Les 2 jeux de résultats compatibles union? (même nombre de colonnes et de types de données correspondants) –

Répondre

2

Que diriez-vous:

$result = mysql_query(' 
      (SELECT * FROM lectures WHERE lecture_id="'.$id.'") 
     UNION 
      (SELECT * FROM lectures_deleted WHERE lecture_id="'.$id.'"); 
     ') 

De cette façon aussi choisir de la lectures_deleted si elle est encore présente dans le tableau des conférences, mais selon votre description je crois que cela ne devrait pas arriver.

Sinon, je suggère d'utiliser un drapeau «supprimé» (un bit bit) dans le tableau des conférences, indiquant si oui ou non la conférence a été supprimée. De cette façon, vous n'avez pas besoin de déplacer une entrée supprimée vers une autre table.

+0

Merci, cela a parfaitement fonctionné! La raison pour laquelle j'ai une table séparée pour les conférences effacées est parce qu'elle est seulement appelée comme une sorte d'option de récupération, et pour rendre le logiciel plus rapide, je voulais minimiser la taille de la table principale quand j'ai demandé. – Ollie

+0

@Ollie Le déplacement des données de tableA à tableB ne rendra pas votre requête plus rapide si vous sélectionnez toujours à la fois tableA et tableB. –

+0

@Andreas Il est uniquement sélectionné à partir des deux tables sur une page de sauvegardes spéciale sur le site Web, qui ne sera pas accessible souvent. – Ollie

1
SELECT 1 AS pref, * FROM lectures WHERE lecture_id="'.$id.'" 
UNION 
SELECT 2 AS pref, * FROM lectures_deleted WHERE lecture_id="'.$id."' 
ORDER BY pref 
LIMIT 0,1 
-1

Je sais que ce n'est pas une réponse exacte à votre question, mais pourquoi ne pas changer votre modèle de données pour avoir quelque chose comme une colonne is_deleted avec une valeur de 0 ou 1 dans votre table lectures? De cette façon, vous n'avez pas besoin de stocker des conférences supprimées dans une table séparée. Vous avez juste à inclure une clause WHERE comme WHERE is_deleted = 0 ou WHERE is_deleted = 1 à vos requêtes pour aller chercher les conférences supprimées ou non supprimées (ou omettre la clause WHERE pour récupérer les deux).

Si vous voulez le résoudre dans votre modèle de données actuel, je le ferais en 2 requêtes. Je ne pense pas que mysql_query soutiendra votre instruction SQL actuelle. Donc, première table de requête lectures et si vous obtenez des résultats de zéro, vérifiez son existence dans lectures_deleted.

En outre, je ne sais pas d'où vient exactement votre variable $id, mais vous voudrez peut-être vous assurer que votre requête n'est pas vulnérable pour SQL injections.

+0

J'ai travaillé avec les deux approches et j'ai trouvé que la vôtre était bien inférieure. Beaucoup mieux IMO pour unir les lignes 'supprimées' que nécessaire pour devoir filtrer 'is_deleted = 0' pour chaque cas normal. – onedaywhen

+0

@onedaywhen: Mieux dans quel sens? Plus rapide? Plus facile à écrire? Plus facile à déboguer? – Sorpigal

+0

Moins de douleur pour le codeur Codeur SQL DML e.g. ne pas avoir à tester 'COALESCE (is_deleted, 'F') = 'F''. Moins de douleur pour le codeur DDL SQL, par ex. ne peut pas simplement utiliser 'UNIQUE' pour la contrainte d'unicité car une valeur peut légitimement être dupliquée pour les entités 'supprimées'. Mieux pour la performance, par ex. ne pas avoir à rejoindre tout le chemin «retour» à la table avec le drapeau «is_deleted». – onedaywhen

0

Votre requête actuelle est erronée parce que vous ne retournez pas quoi que ce soit si la conférence existe dans lectures, vous avez donc besoin de le modifier comme ceci:

IF EXISTS (SELECT * FROM lectures WHERE lecture_id="'.$id.'") 
    SELECT * FROM lectures WHERE lecture_id="'.$id.'" 
ELSE 
    SELECT * FROM lectures_deleted WHERE lecture_id="'.$id.'"; 

Cependant, il vaut mieux en terme de performance d'utiliser le Union -operator dans votre cas car il ne le fera un sélectionner (en supposant que toutes les colonnes dans les deux tableaux sont les mêmes et dans le même ordre):

select * from lectures where lecture_id=$id 
union 
select * from lectures_deleted where lecture_id=$id 
0

la déclaration de décision SI ... ELSE ne peut pas être utilisé dans un diriger la requête MySQL. Il ne peut être utilisé que dans les fonctions/procédures stockées.
Vous pouvez essayer

$result = mysql_query(SELECT * FROM lectures WHERE lecture_id="'.$id.'") 
if (mysql_num_rows($result) == 0) 
    $result = mysql_query(SELECT * FROM lectures_deleted WHERE lecture_id="'.$id.'") 
Questions connexes