【问题标题】:Update row value when record not found on other database在其他数据库上找不到记录时更新行值
【发布时间】:2020-01-12 20:42:57
【问题描述】:

我对 SQL 很陌生。当我在 sx_services_db 表 sx_services_table 中找不到记录时,我需要有关如何将数据库 sx_appmts.db 表“Sx_Appmts_table”中的“AH_Field”更新为“No Show”的帮助。

此代码在找到匹配项并将值“Done”放入 AH_Field 时工作正常,但我想在未找到匹配项时放置“No Show”值。

UPDATE S
SET [AH_Field] = 'Done' 
FROM [SX_Appmts_Db].[dbo].[Sx_Appmts_Table] S 
INNER JOIN [SX_Services_db].[dbo].[Sx_Services_Table] D ON S.[AA_field] = D.[WK_Field] 
WHERE S.[AH_Field] LIKE 'Scheduled' AND
      S.[AA_Field] = D.[WK_Field] AND
      S.[AK_Field] IS NOT NULL AND 
      S.[AQ_Field] IS NOT NULL AND 
      CONVERT(VARCHAR(10), S.[AK_Field], 101) = CONVERT(VARCHAR(10), D.[DV_Field], 101) AND 
      CONVERT(VARCHAR(10), S.[AQ_Field], 101) = CONVERT(VARCHAR(10), D.[AD_Field], 101) AND 
      S.[AD_Field] LIKE D.[AA_Field]

【问题讨论】:

  • 你试过 if /else 吗?
  • 看起来您正在将两个日期字段转换为 varchar 以比较它们,例如convert(varchar(10), S.[AQ_Field], 101) = convert(varchar(10), D.[AD_Field], 101) 这毫无意义,会减慢您的查询速度,您可以使用 sargable 谓词 CONVERT(DATE, S.[AQ_Field]) = CONVERT(DATE, D.[AD_Field]) 实现完全相同的效果
  • 我会试一试,但由于某种原因,当我第一次进行测试时,除非我使用 VARCHAR 进行 CONVERT,否则它不会进行比较。
  • Iria Blanco,你能给我举个例子,当没有找到记录然后将 AH_Field 更新为“No Show”时使用的 CASE

标签: sql-server tsql join


【解决方案1】:

使用LEFT JOIN 而不是INNER JOIN,因为您也想要不匹配的行和CASE 表达式或IIF() 来更新列:

UPDATE S 
SET [AH_Field] = IIF(D.[WK_Field] IS NULL, 'No Show', 'Done') 
FROM [SX_Appmts_Db].[dbo].[Sx_Appmts_Table] S LEFT JOIN [SX_Services_db].[dbo].[Sx_Services_Table] D 
ON    S. [AA_field] = D.[WK_Field] 
  AND S.[AA_Field] = D.[WK_Field]
  AND S.[AD_Field] LIKE D.[AA_Field]
  AND convert(varchar(10), S.[AK_Field], 101) = convert(varchar(10), D.[DV_Field], 101) 
  AND convert(varchar(10), S.[AQ_Field], 101) = convert(varchar(10), D.[AD_Field], 101) 
WHERE S.[AH_Field] LIKE 'Scheduled' AND S.[AK_Field] IS NOT NULL AND S.[AQ_Field] IS NOT NULL 

WHERE 子句中涉及表 [Sx_Services_Table] 中的列的条件已移至 ON 子句以保持 LEFT JOIN 的完整性。
在这种情况下,我也看不到操作员 LIKE 的原因:

S.[AH_Field] LIKE 'Scheduled'

您可以使用= 代替LIKE

【讨论】:

  • 请原谅,但您的查询仍然有 inner join,而不是 left outer join,并且没有 case 表达式。发布代码时是否遗漏了什么?
  • @HABO 谢谢,我设法在代码中错过了我回答的要点.....
  • OK 同意 = 而不是 LIKE。
  • 你能给我举个例子,当没有找到匹配项然后在 AH_Field 中放入“No Show”时,IF 会是什么样子?
【解决方案2】:

重点是LEFT JOIN,但我会对查询进行一些更改:

UPDATE S
    SET AH_Field = (CASE WHEN ST.WK_Field IS NOT NULL THEN 'Done' ELSE 'No Show' END)
    FROM [SX_Appmts_Db].[dbo].[Sx_Appmts_Table] S LEFT JOIN
         [SX_Services_db].[dbo].[Sx_Services_Table] ST
         ON S.[AA_field] = ST.[WK_Field] AND
            CONVERT(DATE, S.AK_Field) = CONVERT(DATE, ST.DV_Field) AND 
            CONVERT(DATE, S.AQ_Field) = CONVERT(DATE, ST.AD_Field) AND 
           S.AD_Field LIKE ST.AA_Field
WHERE S.[AH_Field] = 'Scheduled';

注意事项:

  • 没有必要将列名放在方括号中,除非它们需要加引号(必须引用标识符意味着您选择了错误的标识符)。
  • D --> ST,表名的缩写。
  • 无需重复S.[AA_Field] = D.[WK_Field] 比较。
  • LIKE 'Scheduled' 几乎等同于 = 'Scheduled',但后者的意图更清晰。
  • 日期比较最好使用日期函数,而不是字符串。
  • NULL 的比较是多余的。相等比较已经过滤掉了 NULL 值。

【讨论】:

  • AND WHERE 语法对我来说是新的。我猜应该删除WHERE 以避免将LEFT JOIN 更改为INNER JOIN
  • 我删除了 WHERE 之前的 AND。它执行但没有更新记录。让我更清楚... 我只想更新与 SX_Services_Table 关联的 SX_Appmts_Table 上的记录。如果找到匹配项,则在 AH_Field 中放置“Done”,如果未找到匹配项,则在 AH_Field 中放置“No Show”。
  • 我用来匹配 sx_Appmts_Table 记录的字段是 Chart#(S.AA_Field to D.WK_Field)、Date of Service (S.AK_Field to D.DV_Field)、Date of Birth (S. AQ_Field 到 D.AD_Field),测试类型(S.AD_Field 到 D.AA_Field)和 S.AH_Field 必须具有“计划”。如果我找到匹配项,那么我知道病人进来了,我更新了 S.AH_Field到“完成”,如果没有匹配,那么我知道患者没有完成服务(在 SX_Services_Table 中找不到记录),然后我将 S.AH_Field 更新为“完成”。
  • 这是我推荐后的最后一次更新。更新应该基于是否找到匹配...
  • 更新 S SET AH_Field =(当 WK_Field 不为 NULL 的情况下,'Done' ELSE 'No Show' END)来自 [SX_Appmts_Db].[dbo].[Sx_Appmts_Table] S LEFT JOIN [SX_Services_db]。 [dbo].[Sx_Services_Table] ST ON S.[AA_field] = ST.[WK_Field] WHERE S.[AH_Field] = 'Scheduled' AND convert(DATE, S.AK_Field) = convert(DATE, ST.DV_Field) AND convert (DATE, S.AQ_Field) = 转换(DATE, ST.AD_Field) AND S.AD_Field = ST.AA_Field
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
  • 1970-01-01
  • 2016-01-15
相关资源
最近更新 更多