2010-01-05 7 views
3

J'ai deux tables MySql comme indiqué ci-dessous avec les données indiquées:
La meilleure façon d'écrire cette requête

CREATE TABLE `A` (
`id` int(12) NOT NULL AUTO_INCREMENT, 
`status` varchar(50) DEFAULT NULL, 
`another_field` varchar(50) DEFAULT NULL 
) 

INSERT INTO `A` VALUES ('1', null, 'a'); 
INSERT INTO `A` VALUES ('2', null, 'b'); 
INSERT INTO `A` VALUES ('3', null, 'c'); 


CREATE TABLE `B` (
`id` int(12) NOT NULL AUTO_INCREMENT, 
`status` varchar(50) DEFAULT NULL, 
`tableA_id` int(12) DEFAULT NULL, 
PRIMARY KEY (`id`) 
) 

INSERT INTO `B` VALUES ('1', 'aa', '1'); 
INSERT INTO `B` VALUES ('2', 'aa', '1'); 
INSERT INTO `B` VALUES ('3', 'aa', '2'); 
INSERT INTO `B` VALUES ('4', 'aa', '3'); 
INSERT INTO `B` VALUES ('5', 'bb', '3'); 

Je veux savoir s'il est possible de mettre à jour A.status si tous sont B.status le même lorsque A.id = B.tableA_id en utilisant une seule requête?

C'est ce que je veux ma table A à ressembler à:

('1', 'aa', 'a') - Statut est mis à jour 'aa' comme B.id 1 & 2 ont la même état et même valeur B.tableA_id.
('2', 'aa', 'b') - Le statut est mis à jour à 'aa' car B.id 3 a le même statut.
('3', null, 'c') - Ceci n'est pas mis à jour car B.id 4 & 5 ont un statut différent et la même valeur table2.table1_id.

Merci

+1

Il vous manque quelques points-virgules dans vos requêtes et une définition de clé primaire sur la table un – Anax

+0

Merci pour pointing..please ignorer toutes les erreurs de syntaxe dans les instructions SQL. – codaddict

+0

bzabhi, Anax a raison. Et les définitions de table ne fonctionneraient pas sur MySQL soit en raison de clauses PRIMARY KEY manquantes (doit avoir cela pour AUTO_INCREMENT). S'il vous plaît vérifier votre script la prochaine fois, le rend plus agréable à aider. –

Répondre

8
UPDATE A 
SET status = COALESCE((
      SELECT MAX(B.status) 
      FROM B 
      WHERE B.tableA_id = A.id 
      HAVING MAX(B.status) = MIN(B.status) 
     ), A.status) 

(Note: J'ai ajouté une correction, vous avez besoin du COALESCE(..., A.status) ou autrement, le statut sera défini sur NULL dans le cas où il y avait plusieurs statuts en B

+1

+1, requête très soignée. – gameover

0

ne suis pas sûr MySql mais en MSSQL vous pourriez écrire quelque chose comme:

MISE A JOUR A SET A.Status = 'aa' D'UN INNER JOIN B A.id = B.tableA_id OÙ b.status = 'aa'

Il devrait être similaire dans MySQL, mais je ne suis pas si le langage prend en charge les jointures lors de la mise à jour. Mais encore j'espère que ça aide.

+0

Cette syntaxe fonctionne sous MySQL, mais cette requête ne donne pas le bon résultat. Il mettra A (3) .status = 'aa', même s'il existe deux valeurs de statut differrent pour B (3): 'aa' et 'bb'. –

0
UPDATE a SET status = 
    (
     SELECT status FROM b WHERE tableA_id = a.id LIMIT 0,1 
    ) 
WHERE id IN 
    (
     SELECT tableA_id FROM b 
     GROUP BY tableA_id 
     HAVING COUNT(DISTINCT status) = 1 
    ) 

Mise à jour: Roland avait raison; J'ai mis à jour la requête et elle donne maintenant les résultats corrects.

+0

Cette requête est incorrecte. La sous-requête utilisée dans l'affectation peut et va retourner un ensemble. vous devez ajouter une fonction d'agrégat comme MIN (état) ou MAX (statut), ajouter un mot clé distinct (statut DISTINCT) ou ajouter un statut GROUP BY après l'emplacement. –

+0

J'ai exécuté quelques tests et la requête se comporte comme il se doit. Pouvez-vous fournir un ensemble de données spécifique qui rendra la requête anormale? – Anax

+0

Anax, en rétrospective, en effet votre sous-requête ne retourne pas un ensemble. Mais c'est seulement parce que vous avez un autre problème: la clause WHERE de la première sous-requête: 'WHERE b.tableA_id = id' est fausse. La référence à 'id' devrait être liée à' A.id', mais ce n'est pas le cas - parce que ce n'est pas un alias, cela fait référence à 'B.id'. Alors accidentellement, il cède toujours au plus une rangée. Si vous corrigez votre requête et l'exécutez, vous obtiendrez ERREUR 1242 (21000): La sous-requête renvoie plus d'une ligne. –

-1
CREATE TABLE `A` (
`id` int(12) NOT NULL AUTO_INCREMENT, 
`status` varchar(50) DEFAULT NULL, 
`another_field` varchar(50) DEFAULT NULL 
) 

INSERT INTO `A` VALUES ('1', null, 'a'); 
INSERT INTO `A` VALUES ('2', null, 'b'); 
INSERT INTO `A` VALUES ('3', null, 'c'); 


CREATE TABLE `B` (
`id` int(12) NOT NULL AUTO_INCREMENT, 
`status` varchar(50) DEFAULT NULL, 
`tableA_id` int(12) DEFAULT NULL, 
PRIMARY KEY (`id`) 
) 

INSERT INTO `B` VALUES ('1', 'aa', '1'); 
INSERT INTO `B` VALUES ('2', 'aa', '1'); 
INSERT INTO `B` VALUES ('3', 'aa', '2'); 
INSERT INTO `B` VALUES ('4', 'aa', '3'); 
INSERT INTO `B` VALUES ('5', 'bb', '3'); 
Questions connexes