按照某些条件(一个or多个)分组,取分组中满足某个条件的一条记录:
Sampel1:
SerialNumber SONumber CustomerNumber SOAmount
------------ ----------- -------------- ---------------------------------------
1619648 1216 1370473 0.00
1619649 1216 1370473 0.00
1210509 1216 1370473 0.01
1621946 421648 600121 70.01
1621947 421648 600121 520.02
1210209 1645026 654728 0.00
1210212 1645026 654728 64.70
1210213 1645026 654728 64.70
1210234 1645026 654728 172.35
1210229 1645026 654728 174.48
1210512 1732653 735175 -1.99
1210240 1732653 735175 0.00
1210265 1732653 735175 1000.00
1210267 1732653 735175 5000.00
1210295 1732653 735175 10000.00
1210266 1732653 735175 10000.00
1210268 1732653 735175 100000.00
取SO# 最后一次编辑的数据(同一个SO,SerialNumber 最大的那条)。
SELECT TOP 10 a.*
FROM mis.dbo.SOMasterHistory a WITH (NOLOCK)
WHERE EXISTS
(
SELECT MAX(SerialNumber) --zero amout when placing order
FROM mis.dbo.SOMasterHistory AS b WITH (NOLOCK)
GROUP BY b.SONumber
HAVING a.SONumber=b.SONumber
AND a.SerialNumber=MAX(SerialNumber)
)
Sample2:
GroupID SectionID CreatedTime TextValue
----------- ----------- ------------------------ -----------
1 1 2007-07-10 00:00:00.000 1-1-07-10
1 1 2007-07-11 00:00:00.000 1-1-07/11
1 2 2007-07-05 00:00:00.000 1-2-07/05
1 2 2007-07-11 00:00:00.000 1-2-07-11
1 3 2007-07-13 00:00:00.000 1-3-07-13
2 1 2007-07-10 00:00:00.000 2-1-07-10
2 1 2007-07-11 00:00:00.000 2-1-07-11
2 4 2007-07-09 00:00:00.000 2-4-07-09
其中GroupID, SectionID和CreatedTime是联合主键。当时希望写一个简单的查询,不用CURSOR、不用临时表和临时表变量,希望能得到这样的查询结果:
GroupID SectionID CreatedTime TextValue
----------- ----------- -------------------------- ---------
2 4 2007-07-09 00:00:00.000 2-4-07-09
2 1 2007-07-11 00:00:00.000 2-1-07-11
1 3 2007-07-13 00:00:00.000 1-3-07-13
1 2 2007-07-11 00:00:00.000 1-2-07-11
1 1 2007-07-11 00:00:00.000 1-1-07/11
也就是说,对于每一种(GroupID, SectionID)的组合,取出最后插入的那行。当时一下子还真没想出来怎么写。后来才找到答案的。现在这个问题是我最近使用最多的面试题。
答案如下:
SELECT *
FROM TableInterview AS t1
Where EXISTS
(
SELECT MAX(CreatedTime)
FROM TableInterview AS t2
GROUP BY GroupId, SectionId
HAVING GroupId = t1.GroupId
and SectionId = t1.SectionId
and max(CreatedTime) = t1.CreatedTime
)