如何创建此更新查询?

时间:2014-01-07 22:36:46

标签: sql sql-server

如何构建一个更新查询,该查询将通过下表并将任何col2和col3放在同一行,如果它们具有相同的“日期”值?

ID col1  col2   col3  date
33  10                3/2/2010
35  NULL  200   NULL  3/2/2010
40  NULL  NULL  300   3/2/2010
43  10                3/5/2010
45  NULL  200   NULL  3/7/2010
46  NULL  NULL  310   3/8/2010
53  10                3/9/2010
55  NULL  200   NULL  3/10/2010
58  NULL  NULL  400   3/10/2010

新安排:

ID col1  col2   col3  date
33  10                3/2/2010
35  NULL  200   300   3/2/2010
43  10                3/5/2010
45  NULL  200   NULL  3/7/2010
46  NULL  NULL  310   3/8/2010
53  10                3/9/2010
55  NULL  200   400   3/10/2010

请注意仅限col2和col3的日期2010年3月2日和3月10日的更改。它们位于同一行,并且已删除额外/旧条目。

3 个答案:

答案 0 :(得分:1)

您不仅要更新,还要删除。如果您不想为此编写过程,我想最好的方法是选择结果并将其插入临时表 - 然后可能删除原始表并重命名临时表。

insert into temptable
select min(id), col1, max(col2), max(col3), date
from origtable
group by col1, date

编辑:从col1中删除了max,因为您似乎只想要col2和col3。

答案 1 :(得分:1)

您当前的数据

╔════╦══════╦══════╦══════╦════════════╗
║ ID ║ col1 ║ col2 ║ col3 ║    date    ║
╠════╬══════╬══════╬══════╬════════════╣
║ 33 ║ 10   ║ NULL ║ NULL ║ 2010-03-02 ║
║ 35 ║ NULL ║ 200  ║ NULL ║ 2010-03-02 ║
║ 40 ║ NULL ║ NULL ║ 300  ║ 2010-03-02 ║
║ 43 ║ 10   ║ NULL ║ NULL ║ 2010-03-05 ║
║ 45 ║ NULL ║ 200  ║ NULL ║ 2010-03-07 ║
║ 46 ║ NULL ║ NULL ║ 310  ║ 2010-03-08 ║
║ 53 ║ 10   ║ NULL ║ NULL ║ 2010-03-09 ║
║ 55 ║ NULL ║ 200  ║ NULL ║ 2010-03-10 ║
║ 58 ║ NULL ║ NULL ║ 400  ║ 2010-03-10 ║
╚════╩══════╩══════╩══════╩════════════╝

<强>查询

更新记录

UPDATE T1
SET T1.Col2 = T2.Col2,
    T1.Col3 = T2.Col3
FROM Table_Name T1 INNER JOIN Table_Name T2
ON T1.[date] = T2.[date]
WHERE T1.col1 IS  NULL

删除记录

;WITH Deletebles
AS
  (
   SELECT * , rn = ROW_NUMBER() 
                OVER (PARTITION BY Col2, Col3,[Date] ORDER BY [Date])
   FROM @t
  )
  DELETE FROM Deletebles
  WHERE rn >1

结果集

╔════╦══════╦══════╦══════╦════════════╗
║ ID ║ col1 ║ col2 ║ col3 ║    date    ║
╠════╬══════╬══════╬══════╬════════════╣
║ 33 ║ 10   ║ NULL ║ NULL ║ 2010-03-02 ║
║ 35 ║ NULL ║ 200  ║ 300  ║ 2010-03-02 ║
║ 43 ║ 10   ║ NULL ║ NULL ║ 2010-03-05 ║
║ 45 ║ NULL ║ 200  ║ NULL ║ 2010-03-07 ║
║ 46 ║ NULL ║ NULL ║ 310  ║ 2010-03-08 ║
║ 53 ║ 10   ║ NULL ║ NULL ║ 2010-03-09 ║
║ 55 ║ NULL ║ 200  ║ 400  ║ 2010-03-10 ║
╚════╩══════╩══════╩══════╩════════════╝

答案 2 :(得分:-1)

我不认为更新查询就足够了,因为您必须删除/删除行。以下是选择语句,它将为您提供所需内容...但现在您需要决定是否要有选择地删除不必要的行或删除所有行并重新填充用新的价值观。

编辑:看起来我已经假设Col1可能有多行(因此联合)如果Col1中的欺骗行为可以被淘汰,你可以简单地在组中添加Col1。

SELECT ID, COL1, NULL AS COL2, NULL AS COL3, [DATE]
FROM TBL
UNION ALL
SELECT MIN(ID) AS ID, NULL AS COL1, MAX(COL2), MAX(COL3), [DATE]
FROM TBL
WHERE COL2 IS NOT NULL OR COL3 IS NOT NULL
GROUP BY [DATE]

我用它来测试...

create table tbl (id int, col1 int, col2 int, col3 int, [date] date)

insert into tbl
values (33,10,null,null,'3/2/2010'),
(35,NULL,200,NULL,'3/2/2010'),
(40,NULL,NULL,300,'3/2/2010'),
(43,10,null,null,'3/5/2010'),
(45,NULL,200,NULL,'3/7/2010'),
(46,NULL,NULL,310,'3/8/2010'),
(53,10,null,null,'3/9/2010'),
(55,NULL,200,NULL,'3/10/2010'),
(58,NULL,NULL,400,'3/10/2010')