如何从两个SQL表中获取多个最小值?

时间:2015-12-22 16:13:20

标签: sql-server sql-update min

我有两个表,一个}表和一个Members表。它们的结构如下。

Plan

我需要将member start_date Mplan Pplan version start_dt end_dt John 20120701 johnplan johnplan 1 20120601 20130531 John 20130201 johnplan johnplan 2 20130601 20140531 John 20130901 johnplan John 20131201 johnplan 表上的start_date更新为Members但在同一member版本内的最小值。

实施例

Plan将更改为2013020120120701将更改为20131201

代码:

20130901

不幸的是,这会将每个UPDATE Members SET start_date =( SELECT MIN(start_date) FROM Members a LEFT JOIN Plan ON Mplan = Pplan AND start_date BETWEEN start_dt AND end_dt WHERE member=a.member AND start_date BETWEEN start_dt AND end_dt ) 设置为start_date,也就是该列的整个表中的最低值。

3 个答案:

答案 0 :(得分:1)

首先,您需要获取特定计划的每个成员的最短开始日期。以下内容将为您提供。

select MIN(start_date) as min_date,a.member as member_name,a.Mplan as plan_name    FROM Members a inner JOIN [plan] p ON a.Mplan = p.Pplan AND
    start_date BETWEEN p.start_dt AND p.end_dt
    group by a.member, a.Mplan

结果将是这样的。

min_date                member_name plan_name
2012-07-01 00:00:00.000 John        johnplan1
2013-09-01 00:00:00.000 John        johnplan2

使用此选项更新每个成员的相应计划开始日期最短的计划的开始日期。

update members 
set start_date= tbl.min_date from
(SELECT MIN(start_date) as min_date,a.member as member_name,a.Mplan as   plan_name FROM Members a
    inner JOIN [plan] p ON a.Mplan = p.Pplan AND
    start_date BETWEEN p.start_dt AND p.end_dt
    group by a.member, a.Mplan) as tbl
where member=tbl.member_name and Mplan=tbl.plan_name

我创建了2个表,成员和计划,并使用示例数据测试了此解决方案,并且它可以正常运行。我希望它有所帮助。

答案 1 :(得分:0)

您确实需要将日期转换为日期时间。您将获得更高的精确度,可以存储小时,天和分钟,以及访问日期特定功能,国际转换和本地化。

如果您的列是Varchar(8),那么它使用的空间不会少于Datetime列。

那就是说,你要找的是row_number()。

类似的东西:

SELECT Member, MPlan, Start_Date, Row_Number() OVER (PARTITION BY Member, MPLan ORDER BY Start_Date) as Version
FROM Members

答案 2 :(得分:0)

你可以尝试一下吗?我没有测试它。

With Member_start_dt as
(
    select *, (select start_dt from Pplan where M.start_date <= start_dt AND M.start_date >= end_dt) as Pplan_date
    from Members M
),
Member_by_plan as 
(
    select *, ROW_NUMBER () over (partition by Pplan_date order by start_date) num
    from Member_start_dt
)
update M
Set M.start_date = MBP1.start_date
from  Members M
    inner join Member_by_plan MBP1 ON MBP1.member = M.Member AND num = 1  
    inner join Member_by_plan MBP2 ON MBP2.member = M.Member AND MBP2.Pplan_date = MBP1.Pplan_date AND MBP2.start_date = M.start_date