按T
分组行,并在每个组中查找最大或最小的行(如果值为负),该行中其他行的总和,并删除该行(每个组一个),如果group没有足够的元素来查找sum或者足够但没有行指示其他的总和没有发生
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 :(得分: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 :(得分: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
答案 2 :(得分:1)
使用ABS而不存在
Error The "LinkAssemblies" task failed unexpectedly.
Xamarin.Android.XamarinAndroidException: error XA2006: Reference to metadata item 'System.Runtime.InteropServices.StandardOleMarshalObject' (defined in 'System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089') from 'System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' could not be resolved. ---> Mono.Cecil.ResolutionException: Failed to resolve System.Runtime.InteropServices.StandardOleMarshalObject
at Mono.Linker.Steps.MarkStep.MarkType(TypeReference reference)
at MonoDroid.Tuner.MonoDroidMarkStep.MarkType(TypeReference reference)
at Mono.Linker.Steps.MarkStep.MarkType(TypeReference reference)
at MonoDroid.Tuner.MonoDroidMarkStep.MarkType(TypeReference reference)
at Mono.Linker.Steps.MarkStep.InitializeType(TypeDefinition type)
at Mono.Linker.Steps.MarkStep.InitializeAssembly(AssemblyDefinition assembly)
at Mono.Linker.Steps.MarkStep.Initialize()
at Mono.Linker.Steps.MarkStep.Process(LinkContext context)
at Mono.Linker.Pipeline.Process(LinkContext context)
at MonoDroid.Tuner.Linker.Process(LinkerOptions options, LinkContext& context)
at Xamarin.Android.Tasks.LinkAssemblies.Execute()
--- End of inner exception stack trace ---
at Xamarin.Android.Diagnostic.Error(Int32 code, Exception innerException, String message, Object[] args)
at Xamarin.Android.Tasks.LinkAssemblies.Execute()
at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
at Microsoft.Build.BackEnd.TaskBuilder.<ExecuteInstantiatedTask>d__26.MoveNext() GimcoIOT.Andriod
答案 3 :(得分: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
答案 4 :(得分: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
答案 5 :(得分:1)
您正在寻找每个组的值,该值是所有组的其他值的总和。例如。 4(2,2,4)或-5(-5,-4,-1)。
这通常每组只有一条记录。但它可以是同一数字的多倍。以下是关系的例子:(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;
答案 6 :(得分: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