3

免责声明:我仍在学习 SQL,所以如果我的问题是业余的,或者是一个非常简单的答案,我深表歉意。我没有受过正规培训。我在自学。谢谢。

如果 EMAIL 列为空,则会创建一个特定查询以使用 EMAIL2 列中的数据更新 EMAIL 列。此查询继续从 EMAIL3-6 列中获取数据,如果任何先前的列也为空以尝试填充 EMAIL 列。它目前的位置如下:

update Parents set email = email2 where email = ' ' OR email is null go

update Parents set email = email3 where email = ' ' OR email is null go

update Parents set email = email6 where email = ' ' OR email is null go

(等等)

有没有更简单的方法,使用某种 IF...THEN 类型条件来检查 EMAIL 列中的空白或 null 并根据辅助列中的数据填充它?还需要检查这些列的空白或空值,如果空白或空为真,则跳过这些列。

我很感激可以给出的任何建议。上面的查询有效,只是感觉不是最好的方法。

4

3 回答 3

3

您想要熟悉的一个方便的函数是NULLIF。在您可能希望将值视为 NULL 的情况下,它允许您简化逻辑。例如,如果应用程序将标记值“NA”放入 NULLable 列column1中,NULLIF(column1, 'NA')则将返回所有 NULL 和所有 NA 的 NULL 值。在您的情况下,我们将使用此技巧将空字符串转换为 NULL。

我们要做的另一件事是修剪所有空字符串,这样我们的 NULLIF 只需要检查 '' 的场景(而不是 ''、' '、' '、ad nauseum)。TSQL 仅提供 LTRIM 和RTRIM,我有使用的习惯,RTRIM尽管从任一方向修剪空字符串都会导致我们想要的状态。NULLIF(RTRIM(column1),'')

使用该表达式,我们现在将正确的东西插入到COALESCE函数中。因此

UPDATE
    P
SET
    email = COALESCE(NULLIF(RTRIM(P.email2), ''), NULLIF(RTRIM(P.email3), ''), NULLIF(RTRIM(P.email4), ''))
FROM
    dbo.Parents P
WHERE
    -- This will force a table scan which can be a bad thing for performance
    -- Generally, one should avoid wrapping functions around a column and instead
    -- apply them to the thing being tested
    NULLIF(RTRIM(P.email), '') IS NULL
于 2013-01-08T16:06:53.363 回答
3

你的意思是这样的吗?

update Parents 
      set email = COALESCE(
                    NULLIF(LTRIM(RTRIM(email2), '')),
                    NULLIF(LTRIM(RTRIM(email3), '')),
                    NULLIF(LTRIM(RTRIM(email4), '')),
                    NULLIF(LTRIM(RTRIM(email5), '')),
                    NULLIF(LTRIM(RTRIM(email6), ''))
                  ) 
where email = ' ' OR email is null

LTRIM(RTRIM(email2)

将确保将“”转换为空字符串“”,因为 SQL Server 没有修剪,但有两个单独的函数LTRIMRTRIM. 如果两个表达式相等,NULLIF 返回 null。因此,如果任何电子邮件列为 null 或只是 ' ',它将返回 null。

COALESCE函数将返回第一个表达式的值,即 not null

于 2013-01-08T15:48:24.050 回答
1

不是为了让这成为关于 COALESCE 和 NULLIF 的教程,而是为了证明@billinkc 在他的答案中提供的所有内容,这就是为什么它有效。(对不起,他回答时我正在研究解决方案)。将其放入 SSMS 并查看结果。不过,如上所示的简单更新会很好。

刚刚发现 SQL Fiddle 资源: SQL Fiddle

--Setup the temp table
DECLARE @Parents TABLE (
    ParentsId INT IDENTITY (1,1) PRIMARY KEY,
    email varchar(max),
    email2 varchar(max),
    email3 varchar(max),
    email4 varchar(max),
    email5 varchar(max),
    email6 varchar(max)
)

--This would be the pull from your real Parents Table.
INSERT INTO @Parents 
SELECT
    NULL,'test@domain.com',' ',NULL,NULL,NULL
UNION ALL
SELECT
    NULL,'   ',NULL,NULL,NULL,'test2@domain.com'
UNION ALL
SELECT
    NULL,'',NULL,NULL,NULL,'test3@domain.com'

--Look at the data before we cleanse it
SELECT * FROM @Parents

--Take a look at what COALESCE looks like before the cleanse
SELECT ParentsId, COALESCE(email2,email3,email4,email5,email6) AS NewEmail FROM @Parents

--RUN the NULLIF
UPDATE @Parents SET 
    email2 = NULLIF(email2,' '),
    email3 = NULLIF(email3,' '),
    email4 = NULLIF(email4,' '),
    email5 = NULLIF(email5,' '),
    email6 = NULLIF(email6,' ')

SELECT * FROM @Parents

--Take a look at what COALESCE looks like after the cleanse
SELECT ParentsId, COALESCE(email2,email3,email4,email5,email6) AS NewEmail FROM @Parents
于 2013-01-08T17:00:57.950 回答