2014-11-06 153 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