从另一行复制值

时间:2012-04-30 12:41:15

标签: sql sql-server rows sql-update

我有一个看起来像这样的表:

  ID               AMID           DESC                  value 
  -----------------------------------------------------------------
  100              type A         AMID type A             10
  101              type B         AMID type B             18
  102              type C         AMID type C             34
  101               null            null                   4
  102               null            null                  19
  103              type D         AMID type D              6   
  103              type E            null                  7 

该表包含大约600万行。

现在我希望得到像这样的结果

  ID               AMID           DESC                  value 
  -------------------------------------------------------------
  100              type A         AMID type A             10
  101              type B         AMID type B             18
  102              type C         AMID type C             34
  101              type B         AMID type B              4
  102              type C         AMID type C             19
  103              type D         AMID type D              6   
  103              type E            null                  7

当两个行中的ID的AMID相等时,它显示相同的值,如果AMID不同,则显示相同的值,然后将其保留为...

提前感谢您的帮助..

干杯,

哈里什

3 个答案:

答案 0 :(得分:2)

如果我已正确理解您的要求:

SELECT ID
,      COALESCE(AMID, (
           SELECT TOP 1 AMID FROM Table t2 WHERE t2.ID=ID AND t2.AMID IS NOT NULL
       ))AS AMID
,      DESC                  
,      value  
FROM Table

COALESCE (Transact-SQL)

答案 1 :(得分:2)

首先,让我们设置一些适当的DDL和样本数据:

USE tempdb;
GO

CREATE TABLE dbo.AMID
(
  ID     INT, 
  AMID   VARCHAR(32), 
  [DESC] VARCHAR(32), 
  value  INT
);

INSERT dbo.AMID SELECT 100, 'type A', 'AMID type A', 10
      UNION ALL SELECT 101, 'type B', 'AMID type B', 18
      UNION ALL SELECT 102, 'type C', 'AMID type C', 34
      UNION ALL SELECT 101,  null   , null         , 4
      UNION ALL SELECT 102,  null   , null         , 19
      UNION ALL SELECT 103, 'type D', 'AMID type D', 6   
      UNION ALL SELECT 103, 'type E', null         , 7;

不使用没有ORDER BY的TOP,我甚至不知道它意味着什么,你可以选择一行用于使用partition + order填充NULL行。在你有限的样本数据中,任何ID最多只有两行,但是如果你有更多,这很重要(否则,就像没有ORDER BY的TOP一样,你要拉一些任意行,进行更新不可预测的)。这会按AMID列中的值进行排序,但您可以使用表格中的任何条件更改此值以选择每ID的顶行。

;WITH src AS 
(
  SELECT ID, AMID, [DESC]
  FROM dbo.AMID 
  WHERE AMID IS NULL AND [DESC] IS NULL
),
nv AS 
(
  SELECT ID, AMID, [DESC], rn = ROW_NUMBER() OVER
  (PARTITION BY ID ORDER BY AMID) -- change this ordering accordingly
  FROM dbo.AMID 
  WHERE AMID IS NOT NULL
)
UPDATE src
  SET AMID = nv.AMID, [DESC] = COALESCE(nv.[DESC], src.[DESC])
FROM src INNER JOIN nv
ON src.ID = nv.ID
WHERE nv.rn = 1;

SELECT ID, AMID, [DESC], Value FROM dbo.AMID;

结果:

ID   AMID    DESC         value
---  ------  -----------  -----
100  type A  AMID type A  10
101  type B  AMID type B  18
102  type C  AMID type C  34
101  type B  AMID type B  4
102  type C  AMID type C  19
103  type D  AMID type D  6
103  type E  NULL         7     

别忘了清理:

DROP TABLE dbo.AMID;
GO

除此之外,DESC对于列来说是一个可怕的名称,因为它是一个T-SQL关键字,因此总是必须使用[double quotes]进行转义。< / p>

答案 2 :(得分:1)

select a1.ID,
ISNULL(a1.amid, a3.amid),
a1.[DESC],
a1.value
FROM amid a1
LEFT OUTER JOIN (select a2.id, amid = max(a2.amid)
    from amid a2
    where  a2.amid is not null
    group by a2.id) a3 on a3.id = a1.id

从您的问题中不清楚您正在使用的SQL版本,但上述内容应适用于SQL2000上的任何内容。

基本上,您可以在派生表中调整查询以获得您喜欢的结果。