Tsql T SQL问题:如何基于一行对类似行应用更改';s值

Tsql T SQL问题:如何基于一行对类似行应用更改';s值,tsql,sql-server-2008,Tsql,Sql Server 2008,在我的SQL Server 2008 DB中,我有一个表,表中的记录类似于: ID 1 | Group1 | \ftp\path\group1\file1.txt ID 2 | Group1 | C:\local\file\path\group1\file1.txt ID 3 | Group1 | C:\local\file\path\group1\file1.txt ID 4 | Group1 | C:\local\file\path\group1\file1.txt ID 5 | Group

在我的SQL Server 2008 DB中,我有一个表,表中的记录类似于:

ID 1 | Group1 | \ftp\path\group1\file1.txt
ID 2 | Group1 | C:\local\file\path\group1\file1.txt
ID 3 | Group1 | C:\local\file\path\group1\file1.txt
ID 4 | Group1 | C:\local\file\path\group1\file1.txt
ID 5 | Group2 | \ftp\path\group2\file1.txt
ID 6 | Group2 | C:\local\file\path\group2\file1.txt
ID 7 | Group2 | C:\local\file\path\group2\file1.txt
ID 1 | Group1 | \ftp\path\group1\file1.txt
ID 2 | Group1 | \ftp\path\group1\file1.txt
ID 3 | Group1 | \ftp\path\group1\file1.txt
ID 4 | Group1 | \ftp\path\group1\file1.txt
ID 5 | Group2 | \ftp\path\group2\file1.txt
ID 6 | Group2 | \ftp\path\group2\file1.txt
ID 7 | Group2 | \ftp\path\group2\file1.txt
我需要将表更新为如下所示:

ID 1 | Group1 | \ftp\path\group1\file1.txt
ID 2 | Group1 | C:\local\file\path\group1\file1.txt
ID 3 | Group1 | C:\local\file\path\group1\file1.txt
ID 4 | Group1 | C:\local\file\path\group1\file1.txt
ID 5 | Group2 | \ftp\path\group2\file1.txt
ID 6 | Group2 | C:\local\file\path\group2\file1.txt
ID 7 | Group2 | C:\local\file\path\group2\file1.txt
ID 1 | Group1 | \ftp\path\group1\file1.txt
ID 2 | Group1 | \ftp\path\group1\file1.txt
ID 3 | Group1 | \ftp\path\group1\file1.txt
ID 4 | Group1 | \ftp\path\group1\file1.txt
ID 5 | Group2 | \ftp\path\group2\file1.txt
ID 6 | Group2 | \ftp\path\group2\file1.txt
ID 7 | Group2 | \ftp\path\group2\file1.txt
我只是不知道怎么开始。我很容易在第三列中找到值,因为它们与以下通配符匹配:%:\%

因此,我试图用与该通配符不匹配的记录中的正确值替换与该通配符匹配的字段中的值。该死,很难解释

我可能在解释这个问题上做得不好,但目前我找不到合适的词语


有什么想法吗?我很感谢你的帮助。

像这样的事情,也许吧

UPDATE table
SET table.valueColumn = CT.correctValueColumn
FROM table as CT
    INNER JOIN table as IT on IT.group = CT.group AND CT.valueColumn LIKE '%:\%'
WHERE IT.valueColumn NOT LIKE '%:\%'
我在这台机器上没有management studio,所以我不确定它的语法是否正确


希望这能对你有所帮助。

像这样的事情也许可以

UPDATE table
SET table.valueColumn = CT.correctValueColumn
FROM table as CT
    INNER JOIN table as IT on IT.group = CT.group AND CT.valueColumn LIKE '%:\%'
WHERE IT.valueColumn NOT LIKE '%:\%'
我在这台机器上没有management studio,所以我不确定它的语法是否正确


希望这能有所帮助。

这会得到您展示的结果,但我认为我应用的规则与您描述的方式不匹配。您说的是通配符“%:\%”,但我在任何数据中都看不到类似的内容

DECLARE @foo TABLE
(
    ID VARCHAR(32) PRIMARY KEY, 
    [Group] VARCHAR(32), 
    Val VARCHAR(32)
);

INSERT @foo SELECT   'ID 1','Group1','Value 1'
    UNION ALL SELECT 'ID 2','Group1','Value 2'
    UNION ALL SELECT 'ID 3','Group1','Value 3'
    UNION ALL SELECT 'ID 4','Group1','Value 4'
    UNION ALL SELECT 'ID 5','Group2','A Different Value 1'
    UNION ALL SELECT 'ID 6','Group2','A Different Value 2'
    UNION ALL SELECT 'ID 7','Group2','A Different Value 3';

SELECT ID, [Group], Val FROM @foo;

WITH x AS 
(
    SELECT 
        ID, [Group], Val, 
        rn = ROW_NUMBER() OVER (PARTITION BY [Group] ORDER BY val)
    FROM @foo
)
UPDATE x
    SET x.Val = y.Val
    FROM x 
    INNER JOIN x AS y
    ON x.[Group] = y.[Group]
    WHERE y.rn = 1 AND x.rn > 1;

SELECT ID, [Group], Val FROM @foo;

这是你展示的结果,但我认为我应用的规则与你描述的方式不匹配。您说的是通配符“%:\%”,但我在任何数据中都看不到类似的内容

DECLARE @foo TABLE
(
    ID VARCHAR(32) PRIMARY KEY, 
    [Group] VARCHAR(32), 
    Val VARCHAR(32)
);

INSERT @foo SELECT   'ID 1','Group1','Value 1'
    UNION ALL SELECT 'ID 2','Group1','Value 2'
    UNION ALL SELECT 'ID 3','Group1','Value 3'
    UNION ALL SELECT 'ID 4','Group1','Value 4'
    UNION ALL SELECT 'ID 5','Group2','A Different Value 1'
    UNION ALL SELECT 'ID 6','Group2','A Different Value 2'
    UNION ALL SELECT 'ID 7','Group2','A Different Value 3';

SELECT ID, [Group], Val FROM @foo;

WITH x AS 
(
    SELECT 
        ID, [Group], Val, 
        rn = ROW_NUMBER() OVER (PARTITION BY [Group] ORDER BY val)
    FROM @foo
)
UPDATE x
    SET x.Val = y.Val
    FROM x 
    INNER JOIN x AS y
    ON x.[Group] = y.[Group]
    WHERE y.rn = 1 AND x.rn > 1;

SELECT ID, [Group], Val FROM @foo;

我想你的意思不是&&。可能想在WHERE子句中同时使用这两个like,因为它们可以说是过滤器,而不是连接条件。@t-clausen.dk:我不同意连接。基本上,我也会这么做。不过,语法确实是错误的,
更新表
位(我认为应该是
更新它
,以避免歧义。)这种连接背后的思想是将
的子集链接到所有其他行的补充子集,该子集的值是
比如“%:\%
(值不是
的那些,如“%:\%”
)。后者在前者的基础上进行更新。它看起来很像OP所追求的。@Aaron Bertrand:我同意这有点微妙,可以有不同的解释。在我看来,两个过滤器或两个别名声明都应该交换位置。两个过滤器都定义要连接的子集,因此它们应该d被相应地放置到相应表的位置:如果表在FROM子句中,它的过滤器应该在WHERE子句中,如果表在JOIN子句中,那么它的过滤器应该在JOIN条件所在的ON子句中。我并不是说它应该总是这样,我是在专门讨论这种情况大人物承认错误,我将假装是那个人。对不起,你的连接是正确的。我只是重新阅读了一遍,因为这似乎也是最好的解决方案。更正其他地方,我将负号改为加号。更新t SET t.valueColumn=ct.valueColumn FROM table t internal join table ct on t.group=ct.group和ct.valueC类似“%:\%”的列,其中t.valueColumn不类似“%:\%”这可以使用上面建议的一些更改,并交换ct和t。--从表t中更新ct集ct.valueColumn=t.valueColumn在t.group=ct.group上内部连接表ct,并在t.group=ct.group和ct.valueColumn上类似“%:\%”的列,其中t.valueColumn不类似“%:\%”非常感谢大家!我想你们的意思是这样的,不是这样的&&。可能想在WHERE子句中同时使用这两个like,因为它们可以说是过滤器,而不是连接条件。@t-clausen.dk:我不同意连接。基本上,我很可能会这样做。但是语法确实是错误的,还有
更新表
位(我认为应该是
更新它
,以避免歧义。)此联接背后的思想是将
表的子集
链接到所有其他行的补充子集(这些行的值不是
像“%:\%”的子集
)。后者在前者的基础上进行更新。它看起来很像OP所追求的。@Aaron Bertrand:我同意这有点微妙,可以有不同的解释。在我看来,两个过滤器或两个别名声明都应该交换位置。两个过滤器都定义要连接的子集,因此它们应该d被相应地放置到相应表的位置:如果表在FROM子句中,它的过滤器应该在WHERE子句中,如果表在JOIN子句中,那么它的过滤器应该在JOIN条件所在的ON子句中。我并不是说它应该总是这样,我是在专门讨论这种情况大人物承认错误,我将假装是那个人。对不起,你的连接是正确的。我只是重新阅读了一遍,因为这似乎也是最好的解决方案。更正其他地方,我将负号改为加号。更新t SET t.valueColumn=ct.valueColumn FROM table t internal join table ct on t.group=ct.group和ct.valueC类似“%:\%”的列,其中t.valueColumn不类似“%:\%”这可以使用上面建议的一些更改,并交换ct和t。--从表t中更新ct集ct.valueColumn=t.valueColumn在t.group=ct.group上内部联接表ct,并在t.group=ct.group上与类似“%:\%”的ct.valueColumn和类似“:\%”的ct.valueColumn,其中t.valueColumn不类似“%:\%”非常感谢大家!感谢大家尝试我应该注意到第三列的实际值应该是:c:\blah和z:\blah,等等。换句话说,“正确”值将不包含与通配符%:\%匹配的值,因此需要在与通配符不匹配的一行中使用正确的值进行覆盖。这能更好地解释它吗?谢谢你根据我几乎毫无用处的问题描述来尝试一下我应该注意到第三列的实际值如下:c:\blah和z:\blah,等等