sql update使用select和sub select with join

时间:2014-05-23 19:23:04

标签: sql sql-server

我有一个更新声明,如果满足某些条件,我将用它来更改建筑字段的值。

我告诉它将我的构建值设置为我的select语句的结果

update Table set Building = (select case when child.date determined between child.entry date and child.withdrawal date
then child.building else child.[offender bldg]end

然后我的select语句是另一个select语句的产品,我必须在其中定义date3的值,因为它有空值我需要强制它为当前日期以确保我捕获所有需要的记录更新。

from (select w.BUILDING, [Withdrawal Date] = case when WITHDRAWAL_DATE is null then GETDATE() else w.WITHDRAWAL_DATE end,a.DATE_DETERMINED,w.ENTRY_DATE,a.RESP_BUILDING,o.BUILDING[Offender Bldg]
from dbo._temp_disc_off a inner join dbo.offender o on (a.INCIDENT_ID = o.INCIDENT_ID) inner join dbo.entry w on (o.PERSON_ID = w.STUDENT_ID))child</b>

下一部分与第一个选择语句和符合条件

的建筑物的过滤器相关联
where child.DATE_DETERMINED between child.ENTRY_DATE and child.[Withdrawal Date] and child.RESP_BUILDING is null 
or child.DATE_DETERMINED between child.ENTRY_DATE and child.[Withdrawal Date] and child.RESP_BUILDING <> child.[Offender Bldg])</b>

我必须这样设置,因为我需要比较日期而不是空值,因为我的结果集从2425变为461如果我没有将提款日期设置为getdate()如果为null

当我运行查询时,我收到以下错误: 子查询返回的值超过1。当子查询跟在=, !=, <, <= , >, >=之后或子查询用作表达式时,不允许这样做。

我知道它正在尝试返回多个值,这就是我想要的。但是当我尝试使用IN而不是=时,我得到的语法错误不正确。

该语句未在存储过程中使用,我只是尝试批量更新某些记录。请帮忙,请看看我的语法有点偏差。

提前致谢

使用完整阻止更新了我的问题

*这是我在一个块中的完整声明,自发布以来我对它进行了一些更改,但我正在尝试同样更新临时光盘关闭动作表resp_building字段。我只能在date_determined介于进入和退出日期之间的情况下执行此操作,但在某些情况下,提取日期为空,因此我添加了一个子选择,其中我提供了提取日期的值。

update dbo._temp_disc_off_action 
set RESP_BUILDING = (
     select case when child.DATE_DETERMINED between child.entry_date and child.[Withdrawal Date]
         then child.BUILDING else child.[Offender Bldg] end
     from (
         select w.BUILDING, [Withdrawal Date] = case when WITHDRAWAL_DATE is null 
             then GETDATE() 
             else w.WITHDRAWAL_DATE end,                      
             a.DATE_DETERMINED, w.ENTRY_DATE, a.RESP_BUILDING, o.BUILDING [Offender Bldg]
         from dbo._temp_disc_off_action a 
         inner join dbo.DISC_OFFENDER o 
             on a.INCIDENT_ID = o.INCIDENT_ID 
         inner join dbo.REG_ENTRY_WITH w 
             on o.PERSON_ID = w.STUDENT_ID
         where w.BUILDING = 41) child
      where child.DATE_DETERMINED between child.ENTRY_DATE and child.[Withdrawal Date]  
          and child.RESP_BUILDING is null 
          or child.DATE_DETERMINED between child.ENTRY_DATE and child.[Withdrawal Date]               
          and child.RESP_BUILDING <> child.[Offender Bldg])

2 个答案:

答案 0 :(得分:0)

问题是: 更新表集Building =(子查询)。

您要做的是使用从子查询返回的单个值更新单个列Building。但是,您的子查询返回多个值。因此,它不是Building 4,它为您提供了Building 4,10和19.Sql Server无法将单个列设置为多个值并抛出错误。

最简单的调试方法是将整个update语句转换为select语句,该语句选择原始值和要更新的值。您可以检查结果选择并查看从子选择中重复行的原因,并找出如何返回单个值,或者可能将多个行连接或组合在一起以返回单个值。

答案 1 :(得分:0)

我想通了,我完全使事情变得复杂,并且能够通过简单地运行我在where子句中包含CASE语句的语句来更新我想要的字段。这使我可以检查确定的日期是否在两个日期之间,同时将我的提款日期的空值替换为当前日期。以下是我的发言:

  

更新 dbo._temp_disc_off_action 设置 RESP_BUILDING = w.BUILDING   
FROM
dbo._temp_disc_off_action a
JOIN
dbo.DISC_OFFENDER o ON (a.INCIDENT_ID = o.INCIDENT_ID)< strong>
JOIN dbo.REG_ENTRY_WITH w ON (o.PERSON_ID = w.STUDENT_ID)   
WHERE
a.DATE_DETERMINED BETWEEN w.ENTRY_DATE AND
CASE WHEN w.WITHDRAWAL_DATE IS NULL THEN GETDATE() ELSE w.WITHDRAWAL_DATE END
AND
a.RESP_BUILDING IS NULL AND ** o。 BUILDING = '41'   **或 a.DATE_DETERMINED BETWEEN w.ENTRY_DATE AND CASE WHEN ** w.WITHDRAWAL_DATE **为NULL然后 GETDATE() ELSE w.WITHDRAWAL_DATE 结束   
AND a.RESP_BUILDING&lt;&gt; o.BUILDING AND o.BUILDING = '41'