Comment puis-je limiter un LEFT JOIN pour le 1er résultat dans SQL Server?
J'ai un peu de SQL, qui est presque de faire ce que je veux faire. Je travaille avec trois tables, un des Utilisateurs, UserPhoneNumbers et UserPhoneNumberTypes. Je vais essayer d'obtenir une liste des utilisateurs avec leurs numéros de téléphone pour une exportation.
La base de données elle-même est ancien et a quelques problèmes d'intégrité. Mon problème est qu'il ne doit jamais être 1 type de chaque numéro de téléphone dans la base de données, mais ce n'est pas le cas. Lorsque j'exécute ce je obtenir plusieurs lignes de résultats pour chaque personne si elles contiennent, par exemple, deux "à la Maison" numéros.
Comment puis-je modifier le SQL pour prendre le premier numéro de téléphone indiqué et ignorer les autres numéros? Je suis dans SQL Server et je sais que sur le HAUT de l'instruction. Mais si j'ajoute "TOP 1" à GAUCHE REJOINDRE instruction select sa juste me donner la 1ère entrée dans la base de données, pas la 1ère entrée pour chaque Utilisateur.
C'est pour SQL Server 2000.
Merci,
SELECT Users.UserID,
Users.FirstName, Users.LastName,
HomePhone, WorkPhone, FaxNumber
FROM Users
LEFT JOIN
(SELECT UserID, PhoneNumber AS HomePhone
FROM UserPhoneNumbers LEFT JOIN UserPhoneNumberTypes ON UserPhoneNumbers.UserPhoneNumberTypeID=UserPhoneNumberTypes.UserPhoneNumberTypeID
WHERE UserPhoneNumberTypes.PhoneNumberType='Home') AS tmpHomePhone
ON tmpHomePhone.UserID = Users.UserID
LEFT JOIN
(SELECT UserID, PhoneNumber AS WorkPhone
FROM UserPhoneNumbers LEFT JOIN UserPhoneNumberTypes ON UserPhoneNumbers.UserPhoneNumberTypeID=UserPhoneNumberTypes.UserPhoneNumberTypeID
WHERE UserPhoneNumberTypes.PhoneNumberType='Work') AS tmpWorkPhone
ON tmpWorkPhone.UserID = Users.UserID
LEFT JOIN
(SELECT UserID, PhoneNumber AS FaxNumber
FROM UserPhoneNumbers LEFT JOIN UserPhoneNumberTypes ON UserPhoneNumbers.UserPhoneNumberTypeID=UserPhoneNumberTypes.UserPhoneNumberTypeID
WHERE UserPhoneNumberTypes.PhoneNumberType='Fax') AS tmpFaxNumber
ON tmpFaxNumber.UserID = Users.UserID
- Qui dépend de la version de SQL, vous êtes en train de parler. Si c'est SQL Server 2005+, vous avez de nombreuses options, y compris RANG des requêtes.
- SQL Server est la version 2000.
- La solution est [ici][1], il suffit de remplacer jointure left join. [1]: stackoverflow.com/questions/2043259/...
Vous devez vous connecter pour publier un commentaire.
Depuis SQL Server 2000 et les fonctions de classement sont à l'extérieur, vous pourriez faire de votre sous-requête Sélectionne globale:
iff vous n'avez pas de soins d'Accueil d'un utilisateur numéros sont retournés...
En supposant que SQL Server 2005+, utilisez la fonction ROW_NUMBER:
L'esprit de la
what?
espace réservé pour déterminer le premier numéro. Omettre l'ORDRE, si vous n'avez pas de soins du tout...Chaque fois que vous voulez sélectionner seulement une rangée du haut à partir d'une table de gauche pour chaque ligne dans le tableau de droite, vous devriez envisager d'utiliser l'opérateur apply au lieu de les joindre, et déplacer la condition de jointure à l'intérieur de la jointure gauche:
Dans cette solution, pour chaque utilisateur et le type de numéro de téléphone, je vais chercher la plus faible valeur de clé primaire de la
UserPhoneNumbers
table (j'ai deviné que la colonne a été nomméUserPhoneNumberId
).Je suppose que vous avez quelque champ de clé primaire de chaque table jointe, depuis UserID n'est pas unique. Je vais supposer que votre clé primaire est appelée ID. Nous allons prendre les records avec le plus bas de l'ID. Cela répond à votre "première" des critères.
Il y a un chapitre entier sur ce type de problème, appelé "Ambigu Gruops", dans le livre SQL Antipatterns.
Vous devez définir ce que vous entendez par "premier" quand il y a deux nombres de même type, puis ajouter une condition pour rejoindre, de sorte que seul le bon dossier répond aux critères. Il n'y a pas de raccourci pour cette.
Vous pouvez simplement utiliser GROUP BY:
Au lieu de la fonction min(), vous pouvez utiliser le max() ainsi.
Ou vous pourriez le faire dans un groupe par:
Tiens, juste pour comprendre la question.
Vous ai deux tables:
Tout d'abord il n'est pas nécessaire pour les tables temporaires:
Ajouter des jointures internes si nécessaire.
Ou ai-je raté quelque chose?