2014-11-06 94 views
1

我有一种情况,我需要在where条件中使用更新 语句以及select语句的聚合函数。具有where子句的聚合函数

情况1:

Update test_table 
set ID_Number = 0 
where count(ID_Number)=1; /* Not possible with where */ 

注意:上面的脚本是不可能的where子句。

情况2:

例如,我有如下表:测试

ID_Number Column1 Column2 
-------------------------- 
    1   XYZ  ZYX 
    1   MMM  NNN 
    2   III  JJJ 
    3   AAA  BBB 
    3   CCC  DDD 

现在我需要显示只有那些记录谁的ID_NUMBER是出现两次。

预期结果

ID_Number Column1 Column2 
------------------------------ 
    1   XYZ  ZYX 
    1   MMM  NNN 
    3   AAA  BBB 
    3   CCC  DDD 

我尝试

select * from Test 
group by ID_Number,Column1,Column2 
having count(ID_Number)>1; 

注意:这让我没有什么结果。

回答

2
SET NOCOUNT ON; 
DECLARE @Test TABLE 
(
    ID_Number INT NOT NULL, 
    Column1 VARCHAR(50), 
    Column2 VARCHAR(50) 
); 
INSERT INTO @Test VALUES (1, 'XYZ', 'ZYX'); 
INSERT INTO @Test VALUES (1, 'MMM', 'NNN'); 
INSERT INTO @Test VALUES (2, 'III', 'JJJ'); 
INSERT INTO @Test VALUES (3, 'AAA', 'BBB'); 
INSERT INTO @Test VALUES (3, 'CCC', 'DDD'); 

-- Situation #1 
;WITH cte AS 
(
    SELECT ID_Number 
    FROM @Test 
    GROUP BY ID_Number 
    HAVING COUNT(*) = 1 
) 
UPDATE ts 
SET ts.ID_Number = 0 
FROM @Test ts 
INNER JOIN cte 
     ON cte.ID_Number = ts.ID_Number; 

-- Situation #2 
;WITH cte AS 
(
    SELECT ID_Number 
    FROM @Test 
    GROUP BY ID_Number 
    HAVING COUNT(*) > 1 
) 
SELECT ts.* 
FROM @Test ts 
INNER JOIN cte 
     ON cte.ID_Number = ts.ID_Number; 

输出结果是问题中显示的“预期结果”。

对于这两种情况,CTE都会得到不止一次显示的ID_Number值,并且该值列表用于过滤主要的SELECTUPDATE

+1

这就是我一直在寻找!非常感谢。 – Meem 2014-11-06 06:19:59

0

试试这个:

情况1:

用于更新可以使用Common Table Expressions

Update test_table 
set ID_Number = 0 
where ID_Number IN (
select tst.ID_Number from test_table tst join 
(
select ID_Number,COUNT(*) as CNT from test_table 
GROUP BY ID_Number)d 
ON d.ID_Number=tst.ID_Number 
where d.CNT=1 
) 

情况2:

select tst.ID_Number,Column1,Column2 from test_table tst join 
(
select ID_Number,COUNT(*) as CNT from test_table 
GROUP BY ID_Number)d 
ON d.ID_Number=tst.ID_Number 
where d.CNT>1 

SQL Fiddle

+0

为什么下降?票 – 2014-11-06 06:13:50

+1

我没有downvoted,但会质疑这应该如何工作。通过在ROW_NUMBER()> 1上进行筛选,该查询将筛选出每个所需“组”的第一行。 – 2014-11-06 06:15:26

+0

嗨Ganesh_Delekar,我认为那里有一些错误的地方:哪里CTE.Row = 1 – 2014-11-06 06:26:27

0

首先寻找到你情况2查询以获得您想要的输出将是如下:

SELECT * FROM Test 
WHERE ID_Number IN (select ID_Number from Test 
       group by ID_Number 
       having count(ID_Number)>1) 

现在看看你的情况1你可以编写UPDATE查询用于更新列 :ID_NUMBER = 0仅限于您的更新查询中声明的ID_Number记录一次的记录。

Update test_table 
set ID_Number = 0 
FROM test_table 
WHERE ID_Number IN (select ID_Number from Test 
group by ID_Number 
having count(ID_Number) = 1 
0

这里就是我想要做的:可以按如下修改更新查询

with cte as (
    select *, count(*) over (partition by ID_Number) as c 
    from test_table 
) 
select * 
from cte 
where c > 1