2009-08-13 5 views
1

J'ai une table avec 2 colonnes:SQL - Y at-il une requête qui fera "foreach A dans la table, si! B, insert B"?

nid realm 
1 domain_id 
1 domain_site 
2 domain_id 
3 domain_id 

Je veux que chaque entrée d'avoir 1 entrée id de domaine et 1 pour le site de domaine. Donc, je veux terminer par:

nid realm 
1 domain_id 
1 domain_site 
2 domain_id 
2 domain_site 
3 domain_id 
3 domain_site  

Si je faisais cela en PHP, je venais de foreach à travers toute la liste et insérez la ligne supplémentaire à chaque fois qu'il n'existait pas. Malheureusement, je n'ai que l'accès PHPmyAdmin à cette base de données. Existe-t-il un moyen de le faire en SQL direct?

(Si cela fait une différence: la table a actuellement environ 3000 lignes, dont environ 2.000 lignes seront nécessaires pour insérer une ligne supplémentaire. . uber-slick)

Répondre

2
INSERT IGNORE INTO `table` 
SELECT `alt1`.`nid`, `alt2`.`realm` 
FROM `table` AS `alt1`, `table` AS `alt2` 
+0

ooh, brillant IGNORE mot-clé –

+0

C'est brillant !! Je ne sais pas ce qu'il dit de moi que je ne comprends même pas ce code, mais je l'ai quand même utilisé! Et ça a marché! (J'ai d'abord sauvegardé.) – Eileen

+0

Je suis content que tu aimes ça. :) Il fait quelque chose qui dans la plupart des circonstances serait très mauvais, une jointure sans conditions; Je ne sais pas quel est le terme académique, mais je le considère comme une «jointure explosive», car il en résulte toutes les combinaisons possibles des deux tables. Ici, tout se passe bien parce que vous insérez dans une table avec une contrainte unique, donc vous obtenez juste les combinaisons uniques qui vous intéressent, et le 'IGNORE' fait tomber toutes les combinaisons en double. – chaos

0

Je pense que cela va le faire, mais je ne l'ai pas un endroit pour le tester en ce moment et je suis habitué à Sql Server plutôt que MySQL:

INSERT INTO `table` 
SELECT id.nid, r.realm 
FROM (SELECT nid FROM `table` GROUP BY nid) id 
CROSS JOIN (SELECT realm FROM `table` GROUP BY realm) r 
LEFT JOIN `table` t ON t.nid=id.nid AND t.realm=r.realm 
WHERE t.realm IS NULL 
0
insert into MyTable 
(nid, realm) 
select nid, 'domain_id' 
from MyTable m where not exists (
    select 1 
    from MyTable 
    where MyTable.nid = m.nid and realm = 'domain_id' 
) 
union all 
select nid, 'domain_site' 
from MyTable m where not exists (
    select 1 
    from MyTable 
    where MyTable.nid = m.nid and realm = 'domain_site' 
) 
0

Si vous avez une contrainte UNIQUE sur (nid, realm), vous pourriez faire ceci:

INSERT IGNORE INTO nidTable (nid, realm) 
    SELECT nid, 'domain_site' 
    FROM nidTable WHERE realm = 'domain_id'; 
Questions connexes