2010-04-06 4 views
10

J'ai une question sur l'utilisation de sous-requêtes dans une instruction Update. Mon exemple:sous-requêtes dans UPDATE SET (SQL Server 2005)

UPDATE TRIPS 
    SET locations = city + ', ' FROM (select Distinct city 
             from poi 
             where poi.trip_guid = trips.guid) 

Est-il possible de faire référence à la valeur de la table principale (trips.guid) dans les sous-requêtes?

Lorsque je tente d'utiliser trips.guid je reçois l'erreur:

"The multi-part identifier "trips.guid" could not be bound."

La clause 'select ville Distinct de poi' retour plus d'une ville.

+0

Y a-t-il une garantie d'avoir seulement 1 ville en poi pour un trip_guid (ou est-ce que vous vous attendez à ce que cela se passe pour vous d'une manière ou d'une autre)? –

+0

Il y a au moins 2 cites. L'idée est de mettre toutes les cités dans un seul domaine. – itdebeloper

+0

Votre exemple fonctionne dans Oracle. Pour SQL Server, les autres réponses sont applicables. – Monstieur

Répondre

28

Vous pouvez essayer quelque chose comme

UPDATE trips 
SET  locations = t.city + ', ' + poi.city 
FROM trips t INNER JOIN 
     (
      select Distinct city, trip_guid from poi 
     ) poi ON t.trip_guid = poi.trip_guid 
+5

+1 bien que je ne sois pas d'accord avec le formatage - mettrait le 'INNER JOIN' dans la ligne suivante ;-) –

4

Vous pouvez utiliser des constantes et des valeurs de la sélectionner externe dans la sous-sélection:

Update trips 
Set locations = (Select Distinct trips.city + ', ' + poi.city 
        From poi 
        Where poi.trip_guid = trips.guid) 

Nous ne savons pas comment vos tables ressemblent, donc je ne peux supposer que Distinct travaillera pour vous que façon (renvoyant seulement un city distinct dans la sous-requête).

+4

La sous-requête va se casser si elle renvoie plus de 1 enregistrement –

+0

@Jimmie R. Houts: Correct. Je mettais à jour ma réponse au moment où vous avez posté votre commentaire, merci! –

+0

Avez-vous essayé ceci, il dit ** Syntaxe incorrecte près de 't'.** –

8

Une autre version.

UPDATE trips 
SET locations = trips.city + ', ' + poi.city 
FROM trips INNER JOIN poi 
ON poi.trip_guid = trips.guid 
1

J'ai trouvé la solution - il suffit de déplacer la sous-requête à la

UPDATE TRIPS 
    SET locations = getAllTripCity(guid); 
:) UDF

Mon code source UDF:

CREATE FUNCTION dbo.getAllTripCity(
    @tripGuid uniqueidentifier 
) 
RETURNS nvarchar(200) 
AS 
BEGIN 
DECLARE @cities nvarchar(200); 
set @cities = '' 
select @cities = @cities + city + ' ' from (select DISTINCT city poi where poi.trip_guid = @tripGuid) 
return @ @cities; 
END 

C'est tout ce que vous que je dois faire - travaux bien :)

0

J'ai eu le même problème que l'affiche initiale. Mon cas d'utilisation était le suivant: Une table contenait la date et l'heure d'un événement sportif. Parce que j'obtiens des informations de différentes sources, j'ai changé le schéma de la base de données de sorte que j'avais une valeur int pour l'heure et la date (ou peut-être juste la date) pour la date de l'événement sportif.

Ceci est ma requête:

UPDATE Matches 
SET StartTime= MatchTime.ThisMatchStartTime 
FROM Matches AS M 
INNER JOIN (SELECT CONVERT(int, CONVERT(varchar, DATEPART(Hour, MatchDate)) + RIGHT('00' + CONVERT(varchar, DATEPART(Minute, MatchDate)),2)) AS ThisMatchStartTime, MatchId 
    FROM [Matches] 
    WHERE SportTypeId=16) AS MatchTime ON M.MatchId=MatchTime.MatchId 
WHERE StartTime > 2400 
AND SportTypeId = 16; 

Quelques explications: Vous devez donner la sous-requête MatchStartTime un autre nom, sinon vous obtenez un avertissement/erreur de SQL Server. J'ai aussi dû ajouter MatchId pour savoir que je mettais à jour le bon match. SportTypeId est utilisé pour séparer différents sports dans la base de données.

Merci à @astander de m'avoir orienté dans la bonne direction. Sans son poste, je me serais battu un peu plus pour aboutir à cette solution.