2010-04-06 148 views
10

我有一个在Update语句中使用子查询的问题。我的例子:UPDATE SET中的子查询(sql server 2005)

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

是否有可能在子查询中引用主表值(trips.guid)?

当我尝试使用trips.guid我得到的错误:

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

的条款“SELECT DISTINCT城市从POI”返回一个以上的城市。

+0

是否保证只有一个城市在poi trip_guid(或者你是否期待它为你处理这个问题)? – 2010-04-06 16:34:27

+0

至少有2个引用。这个想法是把所有的cites放在一个领域。 – itdebeloper 2010-04-08 07:56:50

+0

您的示例在Oracle中运行。对于SQL Server,其他答案是适用的。 – Monstieur 2013-06-18 07:40:25

回答

28

你可以尝试像

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,虽然我不同意格式化 - 会将'INNER JOIN'放入下一行;-) – 2010-04-06 16:45:52

4

可以使用常量和值从外部选择的子选择:

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

我们不知道你的表看起来怎么样,所以我只能假设,Distinct会为你的工作(在子查询中只返回一个不同的city)。

+4

如果子查询返回多于一条记录,子查询将中断 – 2010-04-06 16:35:09

+0

@Jimmie R. Houts:正确。我在发布您的评论时更新了我的答案,谢谢! – 2010-04-06 16:36:05

+0

你真的试过这个,它说**'t'附近的语法不正确。** – 2010-04-06 16:39:12

8

另一个版本。

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

我找到了解决办法 - 只要将子查询到UDF :)

UPDATE TRIPS 
    SET locations = getAllTripCity(guid); 

我的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 

这就是你我需要做什么 - 工程罚款:)

0

我和最初的海报有同样的问题。我的使用案例如下: 一个表包含体育赛事的日期和时间。因为我从不同的来源获取信息,所以我更改了数据库的模式,因此我为该运动事件的日期提供了时间和日期时间(或者可能只是日期)的int值。

这是我的查询:

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; 

一些解释: 你必须给子查询MatchStartTime一个不同的名称,否则你从SQL Server中的警告/错误。 我还必须添加MatchId,所以我知道我正在更新正确的Match。 SportTypeId用于分隔数据库中的不同运动。

感谢@astander指引我在正确的方向。如果没有他的职位,我可能会更加努力以达到这个解决方案。