如何从两个 SQL 表中获取多个最小值?
how to get multiple min values from two SQL tables?
我有两个 table,一个 Members
table 和一个 Plan
table。它们的结构如下。
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
我需要将 Members
table 上的 start_date
更新为 member
的最小值,但在相同的 Plan
版本中.
示例:
20130201
将更改为 20120701
,而 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
设置为 19900101
,也就是该列整个 table 中的最低值。
您确实需要将日期转换为日期时间。您将拥有更高的精确度、存储小时、日期和分钟的可能性以及访问日期特定功能、国际转换和本地化。
如果您的列是 Varchar(8),那么它使用的 space 不会少于 Datetime 列。
也就是说,您要查找的是 row_number()。
类似于:
SELECT Member, MPlan, Start_Date, Row_Number() OVER (PARTITION BY Member, MPLan ORDER BY Start_Date) as Version
FROM Members
你能试试这个吗?我没测试。
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
首先您需要获取特定计划的每个成员的最短开始日期。以下将为您提供。
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 个表、成员和计划,并使用示例数据测试了此解决方案并且它有效。希望对你有帮助。
我有两个 table,一个 Members
table 和一个 Plan
table。它们的结构如下。
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
我需要将 Members
table 上的 start_date
更新为 member
的最小值,但在相同的 Plan
版本中.
示例:
20130201
将更改为 20120701
,而 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
设置为 19900101
,也就是该列整个 table 中的最低值。
您确实需要将日期转换为日期时间。您将拥有更高的精确度、存储小时、日期和分钟的可能性以及访问日期特定功能、国际转换和本地化。
如果您的列是 Varchar(8),那么它使用的 space 不会少于 Datetime 列。
也就是说,您要查找的是 row_number()。
类似于:
SELECT Member, MPlan, Start_Date, Row_Number() OVER (PARTITION BY Member, MPLan ORDER BY Start_Date) as Version
FROM Members
你能试试这个吗?我没测试。
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
首先您需要获取特定计划的每个成员的最短开始日期。以下将为您提供。
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 个表、成员和计划,并使用示例数据测试了此解决方案并且它有效。希望对你有帮助。