从行组之间的列值中查找最小值

时间:2014-05-15 15:55:30

标签: sql sql-server tsql

我有一个包含六列的表格:

EKey ABC  XYZ DOB  My_Min Row_Num
---- ---- --- ---- ------ -------
101  AB10 123 1946   100     1    
103  AB10 123 1946   200     2    
201  TN10 456 1955   150     1    
220  TN10 456 1955   240     2    
216  TN10 456 1955    80     3    
214  TN10 456 1955    80     4    

我想计算一个新列Required_Min,其值应如下所示:

EKey ABC  XYZ DOB  My_Min Row_Num Required_Min
---- ---- --- ---- ------ ------- ------------
101  AB10 123 1946   100     1    100
103  AB10 123 1946   200     2    100
201  TN10 456 1955   150     1     80
220  TN10 456 1955   240     2     80
216  TN10 456 1955    80     3     80
214  TN10 456 1955    80     4     80

我正在使用SQL,即SSMS。请帮忙。

5 个答案:

答案 0 :(得分:0)

您可以使用JOIN聚合:{/ p>将MIN表格恢复原状

select t.ekey, t.abc, t.xyz, t.dob, t.my_min, t.rownum,
   t2.required_min
from yourtable t
   join (
      select ekey, min(my_min) required_min
      from yourtable
      group by ekey
   ) t2 on t.ekey = t2.ekey

答案 1 :(得分:0)

我假设ssms意味着sql server。我假设您希望从具有相同“RowNum”的行中获得最小“my_min” 试试这个:

update table_name as outer
   set outer.Required_Min = (select min(My_Min) 
      from table_name as inner 
      where inner.RowNum = outer.RowNum)

-edit -

新假设:ABC + XYZ + DOB形成一个自然键:

update table_name as outer
   set outer.Required_Min = ( select min(My_Min) 
      from table_name as inner 
      where inner.ABC = outer.ABC
      and inner.XYZ = outer.XYZ
      and inner.DOB = outer.DOB )

答案 2 :(得分:0)

如果您的唯一性基于ABC + XYZ + DOB,您可以执行以下操作:

with TableMin as
(select ABC,XYZ,DOB,min(My_min) as My_min
group by ABC,XYZ,DOB
from Table1)
update t1 set t1.Required_Min=tm.My_min
from Table1 t1 inner join TableMin tm on t1.ABC=tm.ABC and t1.XYZ=tm.XYZ and t1.DOB=tm.DOB

但对于拥有大量数据的服务器来说,这种连接非常困难。如果ABC + XYZ在唯一键(甚至ABC)中,请使用此而不是完整的ABC + XYZ + DOB。

答案 3 :(得分:0)

这应该会给你想要的结果:

select EKey         = t.EKey    ,
       ABC          = t.ABC     ,
       XYZ          = t.XYZ     ,
       DOB          = t.DOB     ,
       My_Min       = t.My_Min  ,
       Row_Num      = t.Row_Num ,
       Required_Min = min(t.My_Min) over( partition by t.ABC , t.XYZ , t.DOB )
from dbo.my_table t
order by t.ABC     ,
         t.XYZ     ,
         t.DOB     ,
         t.Row_Num 

如果您确实想要在表格中添加新列,那么您需要执行以下操作:

alter table dbo.my_table add column Required_Min int null
go

update dbo.my_table
set Required_Min = s.Required_Min
from dbo.my_Table t
join ( select ABC , XYZ , DOB , Required_Min = min(My_Min)
       from dbo.my_table
       group by ABC , XYZ , DOB
     ) s on s.ABC = t.ABC
        and s.XYZ = t.XYZ
        and x.DOB = t.DOB
go

alter table dbo.my_table alter column Required_Min int not null
go

update也可以是标准SQL,使用相关子查询而不是派生表。假设合理的索引,执行计划不应该变化太多:

update dbo.my_table
set Required_Min = ( select min(My_Min)
                     from dbo.my_table x
                     where x.ABC = dbo.my_table.ABC
                       and x.XYZ = dbo.my_table.XYZ
                       and x.DOB = dbo.my_table.DOB
                   )

答案 4 :(得分:0)

看起来像是一个关于分析功能的工作PARTITION BY:

select EKey, ABC, XYZ, DOB, My_Min, Row_Num, 
  min(My_Min) OVER (PARTITION BY ABC, XYZ, DOB) as Required_Min
from Stats

另外,我建议您不要将“Required_Min”存储为列,而是在视图或查询中按需计算。否则,您将不得不花时间提供数据相关性(触发器或smth)。因此,我将构建特定的inedex而不是提高查询性能。

相关问题