我的桌子看起来像这样:
group date cash checks
1 1/1/2013 0 0
2 1/1/2013 0 800
1 1/3/2013 0 700
3 1/1/2013 0 600
1 1/2/2013 0 400
3 1/5/2013 0 200
-- 不需要现金只是证明桌子上有更多信息
我想获取日期为最大值且检查大于 0 的每个唯一组。因此返回看起来像:
group date checks
2 1/1/2013 800
1 1/3/2013 700
3 1/5/2013 200
尝试的代码:
SELECT group,MAX(date),checks
FROM table
WHERE checks>0
GROUP BY group
ORDER BY group DESC
问题是它给了我所有的日期和支票,而不仅仅是最大日期行。
使用 MS SQL Server 2005
SELECT group,MAX(date) as max_date
FROM table
WHERE checks>0
GROUP BY group
这适用于获取最大日期..将其加入您的数据以获取其他列:
Select group,max_date,checks
from table t
inner join
(SELECT group,MAX(date) as max_date
FROM table
WHERE checks>0
GROUP BY group)a
on a.group = t.group and a.max_date = date
Inner Join 函数作为过滤器,只获取最大记录。
仅供参考,您的列名很糟糕,不要对列(组、日期、表)使用保留字。
您可以像这样使用window MAX():
SELECT
*,
max_date = MAX(date) OVER (PARTITION BY group)
FROM table
获取每个
group
的最大日期以及其他数据:
group date cash checks max_date
----- -------- ---- ------ --------
1 1/1/2013 0 0 1/3/2013
2 1/1/2013 0 800 1/1/2013
1 1/3/2013 0 700 1/3/2013
3 1/1/2013 0 600 1/5/2013
1 1/2/2013 0 400 1/3/2013
3 1/5/2013 0 200 1/5/2013
使用上面的输出作为派生表,然后您只能获得
date
匹配max_date
的行:
SELECT
group,
date,
checks
FROM (
SELECT
*,
max_date = MAX(date) OVER (PARTITION BY group)
FROM table
) AS s
WHERE date = max_date
;
得到想要的结果。
基本上,这类似于 @Twelfth 的建议,但避免了连接,因此可能更有效率。
您可以在 SQL Fiddle 尝试方法。
使用
in
会对性能产生影响。连接两个子查询不会产生相同的性能影响,可以这样完成:
SELECT *
FROM (SELECT msisdn
,callid
,Change_color
,play_file_name
,date_played
FROM insert_log
WHERE play_file_name NOT IN('Prompt1','Conclusion_Prompt_1','silent')
ORDER BY callid ASC) t1
JOIN (SELECT MAX(date_played) AS date_played
FROM insert_log GROUP BY callid) t2
ON t1.date_played = t2.date_played
SELECT distinct
group,
max_date = MAX(date) OVER (PARTITION BY group), checks
FROM table
应该工作。
SELECT *
INTO #temp
FROM
(
VALUES
(1, '1/1/2013', 0, 0),
(2, '1/1/2013', 0, 800),
(1, '1/3/2013', 0, 700),
(3, '1/1/2013', 0, 600),
(1, '1/2/2013', 0, 400),
(3, '1/5/2013', 0, 200)
) x ([group], date, cash, checks);
-- Method 1
SELECT distinctgroup.[group],
max_date.date,
max_date.cash,
max_date.checks
FROM
(SELECT DISTINCT [group] FROM #temp) distinctgroup
CROSS APPLY
(
SELECT TOP 1
[group],
date,
cash,
checks
FROM #temp t
WHERE distinctgroup.[group] = t.[group]
ORDER BY date DESC
) max_date;
-- Method2
SELECT ot.[group],
ot.date,
ot.cash,
ot.checks
FROM
(SELECT it.[group],
it.date,
it.cash,
it.checks, ROW_NUMBER() OVER (PARTITION BY [group] ORDER BY date DESC) AS rownum
FROM #temp it) ot
WHERE ot.rownum=1
DROP TABLE #temp;