我有这两个表:
项
itemname description belongs
A1 some_text user1
A2 some_text user1
A3 some_text user1
A4 some_text user1
A5 some_text user1
A1 some_text user2
B2 some_text user2
运动
itemname start_date end_date belongs
A1 2013-02-01 2014-01-12 user1
A1 2014-08-14 NULL user1
A1 2014-10-15 2015-01-01 user1
A2 2013-08-03 2014-08-14 user1
A2 2014-08-14 NULL user1
A3 2013-08-02 2014-08-20 user1
A3 2013-12-05 2014-01-07 user1
A4 2013-07-15 2014-09-13 user1
A4 2014-09-13 NULL user1
A5 2013-07-15 2014-09-13 user1
A5 2015-03-11 2016-03-12 user1
A5 2016-03-12 2016-04-13 user1
A1 2015-08-01 2015-08-12 user2
B2 2015-08-13 2015-08-23 user2
我正在玩连接和最大(日期),但没有找到一个有效的解决方案。
user1的结果应如下所示:
itemname description belongs start_date end_date
A1 some_text user1 2014-08-14 NULL
A2 some_text user1 2014-08-14 NULL
A3 some_text user1 2013-08-02 2014-08-20
A4 some_text user1 2014-09-13 NULL
A5 some_text user1 2016-03-12 2016-04-13
如果没有行,我需要具有最高(最新,最新)end_date的行(移动):
end_date = NULL
如果有一行end_date = NULL,我需要这一行的那一行。
这里的难点是max(start_date)的排序不起作用,因为有时候在一个项目的另一个时间段内有一个时间段。
我希望你能理解我的问题。
来自德国的问候:)
答案 0 :(得分:1)
你需要这样的东西
查找每个itemname
&的最新开始日期。 belongs
组合然后将结果返回到最大开始日期以获得结果
SELECT i.itemname,i.description,i.belongs,m.start_date,m.end_date
FROM items i
JOIN movements m
ON i.itemname = m.itemname
AND i.belongs = m.belongs
JOIN (SELECT itemname,
belongs,
Max(COALESCE(end_date, start_date)) AS max_dt,
Max(end_date) AS max_end_dat,
Max(start_date) AS max_start_dat
FROM movements
GROUP BY itemname,
belongs) m1
ON m1.itemname = m.itemname
AND m1.belongs = m.belongs
AND ( ( m.end_date = m1.max_dt
AND m1.max_dt = m1.max_start_dat )
OR ( m1.max_dt = COALESCE(end_date, m.start_date)
AND m1.max_start_dat <> m1.max_dt )
OR ( m1.max_dt = m.start_date
AND m1.max_end_dat <> m1.max_dt ) )
ORDER BY i.belongs,
i.itemname
更新:
SELECT i.itemname,
i.description,
i.belongs,
m.start_date,
m.end_date
FROM items i
JOIN movements m
ON i.itemname = m.itemname
AND i.belongs = m.belongs
JOIN (SELECT itemname,
belongs,
Max(start_date) AS max_dat,
'st' AS indi
FROM movements
WHERE end_date IS NULL
GROUP BY itemname,
belongs
UNION ALL
SELECT itemname,
belongs,
Max(end_date) AS max_dat,
'ed'
FROM movements m
WHERE NOT EXISTS (SELECT 1
FROM movements m1
WHERE m.itemname = m1.itemname
AND m.belongs = m1.belongs
AND end_date IS NULL)
GROUP BY itemname,
belongs) m1
ON m1.itemname = m.itemname
AND m1.belongs = m.belongs
AND ( ( m1.max_dat = m.start_date
AND indi = 'st' )
OR ( m1.max_dat = m.end_date
AND indi <> 'st' ) )
ORDER BY i.belongs,
i.itemname
如果RDBMS
支持ROW_NUMBER
窗口函数或APPLY
运算符
答案 1 :(得分:1)
从一组记录中选择一条记录: 在所有方法中,您可以与Items表一起加入以获取额外信息。
方法-1使用自联接:
Select a.*
from yourTable as a
left join YourTable as b
on b.belongs = a.Belongs
and b.Item_Name=a.Item_Name
and b.Start_date>a.Start_Date
where b.Start_Date is null
方法-2,使用MaxDate。
with MaxDate as(
Select belongs, Item_Name, Max(Start_Date) as MaxDate
from yourTable
group by belongs, Item_Number
) select * from MaxDate as a
inner join YourTable as b
on b.belongs=a.belongs
and b.Item_Number=a.Item_Number
and b.Start_Date=a.MaxDate
方法-3,使用Row_Number标记组中的最后一条记录
with LastRec as(
select *,
Row_Number() over(partition by belongs, Item_number order by Start_date desc) as RN
From yourTable
) select * from LastRec
where rn=1
方法-4,使用子查询获取组中的最后一条记录。
Select * from your table as a
Where a.StartDate=(Select Max(Start_Date) from yourTable as b Where b.belongs=a.belongs and b.Item_Name=a.Item_Number)
答案 2 :(得分:0)
MySQL目前似乎没有ROW_NUMBER()窗口函数。
但它可以通过变量进行模拟。
在下面的示例中,计算@rn
变量。
在MS SQL Server中,将通过ROW_NUMBER() OVER (PARTITION BY itemname,belongs ORDER BY coalesce(end_date,getdate()) desc, start_date desc)
代替。
然后由于WHERE子句rn = 1
,它将仅返回具有最大end_date的移动,其中null被视为max。
select m.itemname, i.description, m.belongs, m.start_date, m.end_date, m.rn
from (
select itemname, belongs, start_date, end_date,
@rn := if(@itemname = itemname and @belongs = belongs, @rn+1,1) as rn,
@itemname := itemname as i,
@belongs := belongs as b
from movements
order by itemname, belongs, coalesce(end_date,'9999-12-31') desc, start_date desc
) m
left join items i on (m.itemname = i.itemname and m.belongs = i.belongs)
where m.rn = 1
order by m.itemname, m.belongs