2015-12-23 1 views
0

J'ai cette table de structure:SQL groupe SUM en ayant SUM

USER_ID | POINTS_BALANCE 

10  | 180   
10  | 20    
10  | 100     
10  | 120 

Comment puis-je mettre à jour champ points_balance par exemple à 500 pour tous ces utilisateurs:

select user_id, sum(points_balance) 
from `user_points_table` 
group by user_id 
having SUM(points_balance) >= 400 && SUM(points_balance) <= 499 

Ou puis-je INSERT une nouvelle ROW pour user_id que having sum(points_balance) entre 400 et 499?

EDIT:

Par exemple:

select user_id, sum(points_balance) 
from `user_points_table` 
where user_id = 74 
group by user_id 
having SUM(points_balance) >= 400 && SUM(points_balance) <= 499 

Résultat:

USER_ID | POINTS_BALANCE 
74  | 434 <-- How can I update this result to 500? 
+2

Modifiez votre question et fournissez les résultats que vous recherchez. –

+0

pouvez-vous expliquer plus quel est le problème que vous rencontrez – essanousy

+0

Alors, voulez-vous augmenter 1 des lignes (si oui, quelle ligne?), Ou ajouter une nouvelle ligne, pour l'augmenter à 500? – Sean

Répondre

0

Vous ne pouvez pas mettre à jour les informations que vous tiriez. Si vous êtes à la recherche d'afficher un numéro différent de ce que vous tiriez, vous pouvez le faire:

select 
    user_id, 
    case 
    when totals < 500 then 500 
    else totals 
    end as totals 
from (
    select user_id, sum(points_balance) as totals 
    from test 
    -- where user_id = 10 
    group by user_id 
    having totals between 400 and 499 
) t 
-- where user_id = 10; 

+---------+--------+ 
| user_id | totals | 
+---------+--------+ 
|  10 | 500 | 
+---------+--------+ 

Si le résultat de

select user_id, sum(points_balance) as totals 
from test 
-- where user_id = 10 
group by user_id 
having totals between 400 and 499; 

est

+---------+--------+ 
| user_id | totals | 
+---------+--------+ 
|  10 | 420 | 
+---------+--------+ 

et que vous voulez cogner cela jusqu'à 500, vous savez que la différence entre 500 et 420 est 80. Alors, insérez un nouvel enregistrement:

insert into test (user_id, points_balance) values (10, 80); 

ou vous pouvez mettre à jour l'un des enregistrements à:

update test set points_balance = points_balance + 80 
where user_id = 10 and points_balance = 120; 

La question suivante - qui des nombreux dossiers de 10 vous mettre à jour? J'espère que vous avez un identifiant pour identifier chaque rangée de manière unique. Si vous avez cela, mettez à jour la ligne avec l'identifiant le plus bas. Si vous n'avez pas de champ qui identifie chaque ligne de manière unique, ce serait le bon moment pour créer un tel champ. Pour ce faire en une seule fois, vous devez créer une procédure stockée ou écrire un script en PHP/Python/quelle que soit la langue dans laquelle vous vous sentez à l'aise.

1

Puisque vous voulez ajouter de nouvelles d'une nouvelle ligne à la table, une option est d'utiliser insert into select:

insert into user_points_table 
select user_id, 500-sum(points_balance) 
from `user_points_table` 
where user_id = 74 
group by user_id 
having SUM(points_balance) >= 400 && SUM(points_balance) <= 499; 
+0

Merci pour votre aide. Ce retour 'Nombre de colonnes ne correspond pas au compte de valeur à la ligne 1'. – simo

0

MISE À JOUR

Comme je comprends votre question, vous cherchez un moyen de définir tous les points d'utilisateurs à un minimum de 500 en ajoutant la différence. Ainsi, votre solution pourrait ressembler à ce qui suit:

mysql> DELIMITER //; 
-> CREATE PROCEDURE updateMinimum() 
-> BEGIN 
-> DECLARE u,s INT; 
-> DECLARE cur CURSOR FOR 
-> SELECT user_id, SUM(points) FROM user_points GROUP BY user_id; 
-> OPEN cur; 
-> read_loop: LOOP 
-> FETCH cur INTO u,s; 
-> IF s < 500 THEN 
->  INSERT INTO user_points (user_id, points) VALUES (u, 500-s); 
-> END IF; 
-> END LOOP; 
-> CLOSE cur; 
-> END// 
mysql> DELIMITER ; 
mysql> CALL updateMinimum(); 

Il vous dira qu'il ya No data, mais ne me dérange pas - il a fait l'affaire.Il suffit d'utiliser SELECT pour le vérifier:

SELECT user_id, SUM(points) FROM user_points GROUP BY user_id; 

Vous pouvez utiliser CALL updateMinimum() chaque fois que vous voulez, en tout temps. Ou si vous n'en avez plus besoin, vous pouvez le supprimer par DROP PROCEDURE updateMinimum();

+0

Comment puis-je le limiter 'IF s> = 400 && IF s <= 499'? Par ailleurs, il renvoie 'Vous avez une erreur dans votre syntaxe SQL; consultez le manuel qui correspond à votre version du serveur MySQL pour la bonne syntaxe à utiliser près de 'DECLARE cur pour SELECT user_id, SUM (points_balance) DE 'user_points_table' à la ligne 2'. – simo

+0

Vous pouvez le limiter en remplaçant «IF s <500 THEN» par «IF s> = 400 AND s <= 499 THEN». Et l'erreur de syntaxe ne devrait pas se produire si la déclaration va après 'BEGIN'. –

+0

Utilisation de: 'DECLARE cur POUR SELECT id_utilisateur, SUM (points_balance) FROM points_utilisateur GROUP BY id_utilisateur; DECLARE CONTINUE MANIPULATEUR POUR NON TROUVE SET done = TRUE; BEGIN OPEN cur; read_loop: BOUCLE FETCH cur INTO, s; SI s> = 400 ET s <= 499 PUIS INSERT INTO user_points (id_utilisateur, points_balance) VALEURS (u, 500-s); FIN SI; FERMER cur; END; ' Il en résulte:' Vous avez une erreur dans votre syntaxe SQL; consultez le manuel qui correspond à votre version du serveur MySQL pour la bonne syntaxe à utiliser près de 'CLOSE cur' à la ligne 1'. – simo