2016-05-20 35 views
-5

T組的行數,並且在每個組中查找最大或最小(如果值爲負數)該行中其他行的總和,然後刪除排(每個組),如果組沒有足夠的元素來發現和或不夠好,但沒有行的指示他人沒有總和發生刪除表中的行,即每組其他行的總和

CREATE TABLE Test (
    T varchar(10), 
    V int 
); 
INSERT INTO Test 
    VALUES ('A', 4), 
      ('B', -5), 
      ('C', 5), 
      ('A', 2), 
      ('B', -1), 
      ('C', 10), 
      ('A', 2), 
      ('B', -4), 
      ('C', 5), 
      ('D', 0); 

預期的結果:

A 2 
A 2 
B -1 
B -4 
C 5 
C 5 
D 0 
+0

請張貼預期的結果。 –

+0

帶更新的問題搜索結果 –

+0

爲什麼D保留? –

回答

1

像評論,這些要求看起來很奇怪。下面的代碼假定求和已經預填充和只是刪除最大/最小隻要最高值不爲0

if object_id('tempdb..#test') is not null 
drop table #test 

CREATE TABLE #Test (
    T varchar(10), 
    V int 
); 
INSERT INTO #Test 
    VALUES ('A', 4), ('B', -5), ('C', 5), ('A', 2), ('B', -1), ('C', 10), ('A', 2), ('B', -4), ('C', 5), ('D', 0); 


if object_id('tempdb..#test2') is not null 
drop table #test2 

SELECT 
T, 
V, 
ABS(V) as absV 
INTO #TEST2 
FROM #TEST 
SELECT * FROM #TEST2 

if object_id('tempdb..#max') is not null 
drop table #max 

SELECT 
T, 
MAX(absV) AS MaxAbsV 
INTO #Max 
FROM #TEST2 
GROUP BY T 
HAVING MAX(AbsV) != 0 



DELETE #TEST2 
FROM #TEST2 
INNER JOIN #MAX ON #TEST2.T = #MAX.T AND #TEST2.absV = #Max.MaxAbsV 

SELECT * FROM #TEST2 
ORDER BY T ASC 
1
; with cte as 
(
    select T, V, 
     R = row_number() over (partition by T order by ABS(V) desc), 
     C = count(*) over (partition by T) 
    from Test 
) 
delete c 
from cte c 
    inner join 
    (
     select T, S = sum(V) 
     from cte 
     where R <> 1 
     group by T 
    ) s on c.T = s.T 
where c.C >= 3 
and c.R = 1 
and c.V = s.S 
1

使用ABS和NOT EXISTS

DECLARE @Test TABLE (
    T varchar(10), 
    V int 
); 
INSERT INTO @Test 
    VALUES ('A', 4), ('B', -5), ('C', 5), ('A', 2), ('B', -1), ('C', 10), ('A', 2), ('B', -4), ('C', 5), ('D', 0); 

    ;WITH CTE as (
    select T,max(ABS(v))v from @Test 
    WHERE V <> 0 
    GROUP BY T) 

SELECT T,V FROM @Test T where NOT exists (Select 1 FROM cte WHERE T = T.T AND v = ABS(T.V)) 
ORDER BY T.T 
+0

不,我得到相同的結果,請你可以在你的機器上執行一次 – mohan111

+0

[** DEMO **](http://data.stackexchange.com/stackoverflow/query/488580)。 'A,5'在這裏不應該被刪除,因爲它不等於'2 + 2'的總和。 –

1

通過檢查SUM(V)是否爲正數來確定行是正數還是負數。然後,確定最小的或最大的值等於其他行的SUM,由SUM(V)MIN(V)如果爲負或MAX(V)減去如屬正數:

DELETE t 
FROM Test t 
INNER JOIN (
    SELECT 
     T, 
     SUM(V) - CASE WHEN SUM(V) >= 0 THEN MAX(V) ELSE MIN(V) END AS ToDelete 
    FROM Test 
    GROUP BY T 
    HAVING COUNT(*) >= 3 
) a 
    ON a.T = t.T 
    AND a.ToDelete = t.V 

ONLINE DEMO

1

可以使用下面的查詢,以獲得所需的輸出: -

select * into #t1 from test 

select * from 
(
select TT.T as T,TT.V as V 
from test TT 
JOIN 
(select T,max(abs(V)) as V from #t1 
group by T) P 
on TT.T=P.T 
where abs(TT.V) <> P.V 

UNION ALL 


select A.T as T,A.V as V from test A 
JOIN(
select T,count(T) as Tcount from test 
group by T 
having count(T)=1) B on A.T=B.T 
) X order by T 

drop table #t1 
0

見若跌破查詢幫助:

DELETE [Audit].[dbo].[Test] FROM [Audit].[dbo].[Test] as AA 
INNER JOIN (select T, 
     CASE 
      WHEN MAX(V) < 0 THEN MIN(V) 
      WHEN MIN(V) > 0 THEN MAX(V) ELSE MAX(V) 
     END as MAX_V, 
     CASE 
      WHEN SUM(V) > 0 THEN SUM(V) - MAX(V) 
      WHEN SUM(V) < 0 THEN SUM(V) - MIN(V) ELSE SUM(V) 
     END as SUM_V_REST 
     from [Audit].[dbo].[Test] 
     Group by T 
     Having Count(V) > 1) as BB ON AA.T = BB.T and AA.V = BB.MAX_V 
1

您正在尋找每個組的值,它是所有組的其他值的總和。例如。 (2,2,4)或-5(-5,-4,-1)中的4。

這通常只有一組記錄。但它可以是相同數量的多倍。以下是關係示例:(0,0)或(-2,2,4,4)或(-2,-2,4,4,4)或(-10,3,3,3,3, 4)。

正如你所看到的,你正以任何方式尋找等於組總和一半的值。 (當然,我們正在尋找n + n,其中一個n在一個記錄中,另一個n是所有其他記錄的總和)。

唯一的特例是,當只有一個值這是零的組。我們當然不想刪除。

這裏是不能用的關係處理的更新語句,但會刪除所有的最大值,而不是隻有一個:

delete from test 
where 2 * v = 
(
    select case when count(*) = 1 then null else sum(v) end 
    from test fullgroup 
    where fullgroup.t = test.t 
); 

爲了應對關係,你需要人工行號,以便刪除只有所有候選人的記錄。

with candidates as 
(
    select t, v, row_number() over (partition by t order by t) as rn 
    from 
    (
    select 
     t, v, 
     sum(v) over (partition by t) as sumv, 
     count(*) over (partition by t) as cnt 
    from test 
) comparables 
    where sumv = 2 * v and cnt > 1 
) 
delete 
from candidates 
where rn = 1; 

SQL小提琴:http://sqlfiddle.com/#!6/6d97e/1