2008-09-24 5 views
1

J'ai deux tables, les utilisateurs et DoctorVisitCalculer les utilisateurs de poids moyen

utilisateur - UserID - Nom

DoctorsVisit - UserID - Poids - Date

Le tableau doctorVisit contient toutes les visites d'un utilisateur particulier fait au médecin. Le poids de l'utilisateur est enregistré par visite.

Requête: additionne tout le poids de l'utilisateur en utilisant les chiffres de la dernière visite du médecin. (puis diviser par le nombre d'utilisateurs pour obtenir le poids moyen)

Remarque: certains utilisateurs peuvent ne pas avoir consulté le médecin du tout, tandis que d'autres peuvent avoir visité plusieurs fois.

J'ai besoin du poids moyen de tous les utilisateurs, mais en utilisant le poids le plus récent.

Mise à jour

Je veux que le poids moyen à tous les utilisateurs.

+0

Avez-vous besoin du poids moyen de tous les utilisateurs, ou du poids moyen d'un utilisateur consulté par un médecin? –

+0

Pourquoi l'étiquette de devoirs, avec quelques commentaires, a-t-elle été supprimée? –

+0

Je pense que c'est OK pour enlever la balise de devoir, cependant, enlever des commentaires était inapproprié. – Swati

Répondre

0

Cela devrait vous obtenir le poids moyen par utilisateur s'ils ont visité:

select user.name, temp.AvgWeight 
from user left outer join (select userid, avg(weight) 
      from doctorsvisit 
      group by userid) temp 
    on user.userid = temp.userid 
+0

Je ne pense pas que ce soit ce qui a été demandé. Je pense que la question était le poids moyen à la dernière série de visites du médecin. –

0

Ecrire une requête pour sélectionner le poids le plus récent pour chaque utilisateur (QueryA), et utiliser cette requête comme une sélection interne de une requête pour sélectionner la moyenne (QueryB), par exemple,

SELECT AVG(weight) FROM (QueryA) 
+0

sélection interne d'une requête = sous-requête –

4

Si je comprends bien votre question, vous devriez être en mesure d'obtenir le poids moyen de tous les utilisateurs en fonction de leur dernière visite de l'instruction SQL suivante. Nous utilisons une sous-requête pour obtenir la dernière visite en tant que filtre.

SELECT avg(uv.weight) FROM (SELECT weight FROM uservisit uv INNER JOIN 
(SELECT userid, MAX(dateVisited) DateVisited FROM uservisit GROUP BY userid) us 
ON us.UserID = uv.UserId and us.DateVisited = uv.DateVisited 

Je dois préciser que cela suppose qu'il existe un ID utilisateur unique qui peut être utilisé pour déterminer l'unicité. En outre, si le DateVisited n'inclut pas une heure mais juste une date, un patient qui visite deux fois le même jour pourrait fausser les données.

+0

Cela suppose qu'il existe une clé unique sur UserId et DateVisited (ce qui devrait être une hypothèse assez sûre - mais devrait néanmoins être souligné). –

+0

J'aime l'utilisation de sous-requêtes avec des jointures. Très efficace. Il est également supposé que le même utilisateur ne viendra pas deux fois par jour chez le médecin. Ce qui est probablement une hypothèse sûre. – Jonathan

0

Je pense qu'il y a une erreur dans vos spécifications.

Si vous divisez par tous les utilisateurs, votre moyenne sera trop faible. Chaque utilisateur qui n'a pas de visites chez le médecin aura tendance à faire glisser la moyenne vers zéro. Je ne crois pas que ce soit ce que tu veux. Je suis trop paresseux pour arriver à une requête réelle, mais ce sera une de ces choses où vous utilisez une auto-jointure entre la table de base et une requête avec un groupe qui retire tout l'identifiant approprié , Paires de date de visite de la table de base. La seule chose dont vous avez besoin pour la table User est le nom.

Nous avons eu un échantillon du même problème ici il y a quelques semaines, je pense. Par le "même problème", je veux dire le problème où nous voulons un attribut du représentant d'un groupe, mais où l'attribut que nous voulons n'est pas inclus dans la clause group by.

+0

Je peux m'assurer de ne calculer que les valeurs wehre un poids> 0 –

+0

coalesce corrige ce n'est pas? Je ne suis pas sûr.. –

0

Je pense que cela fonctionne, si je peux me tromper:

Utilisez une sélection interne pour vous assurer que vous avez la dernière visite, puis utilisez AVG. Votre table User dans cet exemple est superflue: puisque vous n'avez pas de données de poids et que vous ne vous souciez pas des noms d'utilisateur, cela ne vous convient pas de l'examiner.

SELECT AVG(dv.Weight) 
FROM DoctorsVisit dv 
WHERE dv.Date = (
     SELECT MAX(Date) 
     FROM DoctorsVisit innerdv 
     WHERE innerdv.UserID = dv.UserID 
) 
0

Si vous utilisez SQL Server 2005, vous n'avez pas besoin de la sous-requête sur GROUP BY.
Vous pouvez utiliser la nouvelle fonctionnalité ROW_NUMBER et PARTION BY. Comme quelqu'un d'autre l'a mentionné cependant, c'est le poids moyen de tous les utilisateurs qui ont consulté le docteur. Si vous voulez le poids moyen pour tous les utilisateurs, toute personne qui ne visite pas le médecin donnera une moyenne trompeuse.

0

Voici mon coup de couteau à la solution:

select 
    avg(a.Weight) as AverageWeight 
from 
    DoctorsVisit as a 
innner join 
    (select 
     UserID, 
     max (Date) as LatestDate 
    from 
     DoctorsVisit 
    group by 
     UserID) as b 
    on a.UserID = b.UserID and a.Date = b.LatestDate; 

Notez que la table utilisateur n'est pas du tout utilisé.

Cette moyenne omet entièrement les utilisateurs qui n'ont pas du tout de visites chez le médecin ou dont le poids est enregistré comme NULL lors de leur dernière visite chez le médecin. Cette moyenne est faussée si des utilisateurs ont plus d'une visite à la même date, et si la dernière date est l'une de celles où l'utilisateur a été plus d'une fois.

Questions connexes