通过SQL更新组中的多个行

时间:2014-01-06 23:18:49

标签: sql sql-server

我有一张看起来像这样的表

+----------------------------+
| id    | bdate     | item    |
+----------------------------+
|    1  | 20010101 |       1a |
|    1  | 20020202 |       1b |
|    1  | 20030303 |       1c |
|    2  | 20010101 |       1d |
|    2  | 20020202 |       1e |
+----------------------------+

我想将bdate更新为今天按ID分组,其中bdate不是最大值。因此对于上述记录,执行查询后结果将如下所示。

+----------------------------+
| id    | bdate     | item    |
+----------------------------+
|    1  | 20140106 |       1a |
|    1  | 20140106 |       1b |
|    1  | 20030303 |       1c |
|    2  | 20140106 |       1d |
|    2  | 20020202 |       1e |
+----------------------------+

我想出了使用临时表的结果,但想看看有没有人有更好的建议。

谢谢,

3 个答案:

答案 0 :(得分:1)

这样做

UPDATE t
   SET bdate = GETDATE()
  FROM table1 t LEFT JOIN 
(
  SELECT id, MAX(bdate) bdate
    FROM table1
   GROUP BY id
) e
    ON t.id = e.id
   AND t.bdate = e.bdate
 WHERE e.id IS NULL;

结果:

| ID |      BDATE | ITEM |
|----|------------|------|
|  1 | 2014-01-06 |   1a |
|  1 | 2014-01-06 |   1b |
|  1 | 2003-03-03 |   1c |
|  2 | 2014-01-06 |   1d |
|  2 | 2002-02-02 |   1e |

这是 SQLFiddle 演示

答案 1 :(得分:0)

我在这里假设您已经使用数据构建了表格(根据您的示例)。

假设您将表命名为“MainTable”,我的观点如下:

UPDATE MT
    SET bdate = CASE WHEN MT2.bdate IS NULL THEN GETDATE() ELSE MT2.bdate END
  FROM MainTable AS MT
    LEFT JOIN (
                SELECT
                      ID
                      ,bdate = MAX(bdate)
                   FROM MainTable
                   GROUP BY ID
               ) MT2
       ON MT2.ID = MT.ID
       AND MT2.bdate = MT.bdate

现在我猜这个逻辑应该非常接近你的临时表逻辑,除了这是使用子查询(为了更快地工作)。 这也假设“项目”列与您的目的无关。

答案 2 :(得分:0)

测试数据

DECLARE @t TABLE (ID INT,BDate VARCHAR(10),Item VARCHAR(10))
INSERT INTO @t
VALUES 
(1,'20010101','1a'), 
(1,'20020202','1b'),
(1,'20030303','1c'),
(2,'20010101','1d'),
(2,'20020202','1e')

<强>查询

;WITH MaxDates
AS
  (
   SELECT *, rn = RANK() OVER (PARTITION BY ID ORDER BY BDate DESC)
   FROM @t
  )
UPDATE MaxDates
SET BDate =  CONVERT(VARCHAR(8), GETDATE(), 112)
FROM MaxDates
WHERE rn > 1

SELECT *
 FROM @t

结果集

╔════╦══════════╦══════╗
║ ID ║  BDate   ║ Item ║
╠════╬══════════╬══════╣
║  1 ║ 20140106 ║ 1a   ║
║  1 ║ 20140106 ║ 1b   ║
║  1 ║ 20030303 ║ 1c   ║
║  2 ║ 20140106 ║ 1d   ║
║  2 ║ 20020202 ║ 1e   ║
╚════╩══════════╩══════╝