我的表数据如下所示
declare @t table (name varchar(10), amt int, dt datetime)
insert into @t (name, amt, dt)
values
('meeseva',100,'06-17-2015'), ('meeseva',200,'06-17-2015'),
('meeseva',200,'06-17-2015'), ('meeseva',100,'06-16-2015'),
('meeseva',100,'06-15-2015'), ('meeseva',100,'06-14-2015'),
('fish',100,'06-17-2015'), ('fish',200,'06-17-2015'),
('fish',100,'06-16-2015'), ('fish',200,'06-16-2015'),
('fish',100,'06-15-2015'), ('fish',100,'06-14-2015'),
('raju',100,'06-17-2015'), ('raju',200,'06-17-2015'),
('raju',100,'06-16-2015'), ('raju',100,'06-15-2015'),
('raju',100,'06-14-2015'), ('raju',500,'06-14-2015')
到目前为止,我已经尝试了
select
name,
SUM(amt),
dt,
ROW_NUMBER() OVER (PARTITION BY name order by dt)
from
@t
where
dt >= (SELECT CONVERT (VARCHAR(10), Getdate() - 4, 101))
and dt <= (SELECT CONVERT (VARCHAR(10), Getdate(), 101))
GROUP BY
name, dt
ORDER BY
name, dt desc
我有数据需要根据金额和每天的总和来获取数据如果金额基于记录ID和日期应该返回最高的两个总数应该返回。
我想要的输出:
name sum dt
-----------------------------------
fish 300 2015-06-17 00:00:00.000
meeseva 500 2015-06-17 00:00:00.000
fish 300 2015-06-16 00:00:00.000
raju 200 2015-06-16 00:00:00.000
fish 100 2015-06-15 00:00:00.000
meeseva 100 2015-06-15 00:00:00.000
raju 600 2015-06-14 00:00:00.000
meeseva 100 2015-06-14 00:00:00.000
答案 0 :(得分:4)
你可以试试这个
;WITH ranking AS(
SELECT name,
SUM(amt) [sum],
dt,
RANK() OVER (PARTITION BY dt ORDER BY SUM(amt) DESC, name -- use recordid here to order by sum then recordnumber
) AS rnk
FROM @t
WHERE dt >= DATEADD(DAY, -4, CONVERT(DATE, GETDATE()))
GROUP BY name,
dt
)
SELECT name,
[sum],
dt
FROM ranking
WHERE rnk <= 2
ORDER BY dt DESC,
name
答案 1 :(得分:2)
请阅读我对这个问题的评论。以下是一个示例查询:
SELECT *
FROM (
SELECT *, ROW_NUMBER() OVER(PARTITION BY dt ORDER BY amt DESC) AS RowNo
FROM @t
) T
WHERE RowNo IN (1, 2)
ORDER BY dt DESC
<强> [编辑] 强>
更适合您的问题描述示例:
SELECT t.*
FROM (
SELECT name, dt, SUM(amt) AS amt, ROW_NUMBER() OVER(PARTITION BY dt ORDER BY SUM(amt) DESC) AS RowNo
FROM @t
WHERE dt BETWEEN ... AND ...
GROUP BY name, dt
) T
WHERE RowNo IN (1, 2)
ORDER BY dt DESC
答案 2 :(得分:2)
你有一些正确的想法。但是row_number()
需要进入子查询或CTE。您的日期算术也可以简化 - 将日期/时间转换为varchar以与日期进行比较是没有意义的。而且,您有一个存储日期的datetime
列。值上允许使用时间组件(暗示),或者您应将列更改为date
。
所以:
select t.*
from (select name, CAST(dt as DATE) as dt, sum(amt),
row_number() over (partition by name order by sum(amt) desc) as seqnum
from @t t
where dt >= CAST(Getdate() - 4 as date) and
dt <= CAST(Getdate() as date)
group by name, CAST(dt as DATE)
) t
where seqnum <= 2
order by name, dt desc;
答案 3 :(得分:2)
试试这个
DECLARE @t TABLE (
name varchar(10),
amt int,
dt datetime
)
DECLARE @topRows int = 2
INSERT INTO @t (name, amt, dt)
VALUES ('meeseva', 100, '06-17-2015'),
('meeseva', 200, '06-17-2015'),
('meeseva', 200, '06-17-2015'),
('meeseva', 100, '06-16-2015'),
('meeseva', 100, '06-15-2015'),
('meeseva', 100, '06-14-2015'),
('fish', 100, '06-17-2015'),
('fish', 200, '06-17-2015'),
('fish', 100, '06-16-2015'), ('fish', 200, '06-16-2015'), ('fish', 100, '06-15-2015'), ('fish', 100, '06-14-2015'),
('raju', 100, '06-17-2015'), ('raju', 200, '06-17-2015'),
('raju', 100, '06-16-2015'), ('raju', 100, '06-15-2015'), ('raju', 100, '06-14-2015'), ('raju', 500, '06-14-2015')
SELECT
name,
SUM(amt) [totalsum],
dt,
ROW_NUMBER() OVER (PARTITION BY dt ORDER BY SUM(amt) DESC, name) rw INTO #temp
FROM @t
WHERE dt >= (SELECT
CONVERT(varchar(10), GETDATE() - 4, 101))
AND dt <= (SELECT
CONVERT(varchar(10), GETDATE(), 101))
GROUP BY name,
dt
ORDER BY dt DESC
SELECT
*
FROM #temp
WHERE rw <= @topRows
ORDER BY dt DESC
DROP TABLE #temp