Je souhaite croiser certaines données d'enquête pondérées dans un contexte où un individu peut contribuer à plus d'une cellule. Le défi consiste à s'assurer que les sous-totaux et les totaux généraux sont effectués sans double comptage.Pondérations SQL non distinctes pour des lignes distinctes avec des totaux par catégorie
Je peux obtenir les valeurs de cellules individuelles mais pas les totaux en utilisant des méthodes similaires aux solutions à How do I SUM DISTINCT Rows? ou Sum Distinct By Other Column. J'essaie d'utiliser l'instruction Oracle CUBE pour obtenir les totaux de manière agréable.
Voici un exemple de bébé. Supposons que nous comptons les gens selon leurs animaux de compagnie et selon leurs passe-temps. Le problème est qu'une personne peut avoir plus d'un animal de compagnie, ou plus d'un passe-temps. Nous devons transformer cet ensemble d'enregistrements unitaires:
person_id, weight
1, 10
2, 10
3, 12
person_id, pet
1, "cat"
1, "dog"
2, "cat"
3, "cat"
person_id, hobby
1, "chess"
2, "chess"
2, "skydiving"
3, "skydiving"
dans cette paire de tables:
Unweighted count
| chess | skydiving | total
------+-------+-----------+--------
cat | 2 | 2 | 3
------+-------+-----------+--------
dog | 1 | 0 | 1
------+-------+-----------+--------
total | 2 | 2 | 3
Weighted count
| chess | skydiving | total
------+-------+-----------+--------
cat | 20 | 22 | 32
------+-------+-----------+--------
dog | 10 | 0 | 10
------+-------+-----------+--------
total | 20 | 22 | 32
Notez que le total non pondéré de la ligne "chat" est 3, et non 2 + 2 = 4 , puisque la personne numéro 2 est comptée à deux endroits différents. Seulement trois personnes distinctes contribuent à cette rangée. De même pour les autres totaux.
Notez que le total pondéré pour "chat, échecs" est 20 = 10 + 10, car deux personnes différentes contribuent chacune poids 10 à cette cellule.
Notez que le total général pour le tableau pondéré est de 32. Cela vient des personnes 1 et 2 qui contribuent 10 chacune, et la personne 3 qui en donne 12. Le total général n'est pas seulement la somme de toutes les cellules individuelles!
Pour les comptes non pondérés, je peux obtenir tous les chefs de cellules et totaux par:
CREATE TABLE weights(person_id INTEGER, weight INTEGER);
INSERT INTO weights(person_id,weight) VALUES (1,10);
INSERT INTO weights(person_id,weight) VALUES (2,10);
INSERT INTO weights(person_id,weight) VALUES (3,12);
CREATE TABLE pets(person_id INTEGER, pet VARCHAR(3));
INSERT INTO pets(person_id,pet) VALUES (1,'cat');
INSERT INTO pets(person_id,pet) VALUES (1,'dog');
INSERT INTO pets(person_id,pet) VALUES (2,'cat');
INSERT INTO pets(person_id,pet) VALUES (3,'cat');
CREATE TABLE hobbies(person_id INTEGER, hobby VARCHAR(9));
INSERT INTO hobbies(person_id,hobby) VALUES (1,'chess');
INSERT INTO hobbies(person_id,hobby) VALUES (2,'chess');
INSERT INTO hobbies(person_id,hobby) VALUES (2,'skydiving');
INSERT INTO hobbies(person_id,hobby) VALUES (3,'skydiving');
SELECT pet, hobby, COUNT(DISTINCT weights.person_id)
FROM weights JOIN pets on weights.person_id=pets.person_ID
JOIN hobbies on weights.person_id=hobbies.person_id
GROUP BY CUBE(pet, hobby);
La combinaison de COUNT(DISTINCT ...)
et CUBE
donne les totaux corrects.
Pour comptes pondérés, si je tente la même idée:
SELECT pet, hobby, SUM(DISTINCT weight)
FROM weights JOIN pets on weights.person_id=pets.person_ID
JOIN hobbies on weights.person_id=hobbies.person_id
GROUP BY CUBE(pet, hobby);
la cellule « chat, jeu d'échecs » vient à 10 pas 20, parce que les gens 1 et 2 ont tous deux le même poids. Supprimer le mot clé «distinct» signifie que les comptes de cellules individuels sont corrects mais que les totaux sont faux (il produit un grand total de 52 où il devrait être de 32, car les personnes 1 et 2 sont comptées deux fois dans le total).
Des suggestions?
si vous supprimez la somme distincte à l'intérieur? –
Vous voulez dire SUM (poids)? Alors la cellule "chat, échecs" est correcte, mais le total général est de 52 où il devrait être de 32, car les personnes 1 et 2 sont comptées deux fois chacune dans le total général. –
mais somme (poids distinct) donne le total 22 pas 32. –