我一直试图编写一个SQL查询,以选择每个用户每种类型的前3名,然后与每种用户另一种类型的前1名求和。如果听起来很复杂,我深表歉意,但我想不出更好的方式来形容它。该查询必须与MySQL 5.x兼容。
我一直在尝试适应以前的查询,但并不高兴。当前已设置为每位用户返回每种类型的前5行,每隔一行将其值1对待。我试图更改一些子句以产生期望的效果,而不会感到高兴。
SELECT
wsf_ref
,sum(wsf_value) as total
from (select
*,
( select count(*)
from individual u
where
t.wsf_ref = u.wsf_ref and
t.type = u.type and
t.wsf_value <= u.wsf_value
) as number
from individual t) t
where (number <= 3 and type <> 'blue' and status = 'Approved' and wsf_progress IN ('Day 1', 'Day 2', 'Day 3'))
or (number = 1 and type = 'blue' and status = 'Approved' and wsf_progress IN ('Day 1', 'Day 2', 'Day 3'))
group by wsf_ref
order by total desc
Example Data
-------------------------------
id wsf_ref status type wsf_progress wsf_value
1 001 Approved orange Day 1 5
2 001 Approved orange Day 1 10 *
3 001 Approved orange Day 1 20 *
4 001 Approved orange Day 1 10 *
5 001 Approved blue Day 1 10
6 001 Approved blue Day 1 25 *
7 002 Approved red Day 1 10
8 002 Approved red Day 1 20 *
9 002 Approved red Day 1 30 *
10 002 Approved red Day 1 20 *
11 002 Approved orange Day 1 10
12 002 Approved orange Day 1 20 *
13 002 Approved orange Day 1 15 *
14 002 Approved orange Day 1 40 *
15 002 Approved blue Day 1 20
16 002 Approved blue Day 1 35
17 002 Approved blue Day 1 50 *
* denotes rows to be summed in the example.
在此示例中,“蓝色”的类型仅是TOP 1。在此示例中,“状态”和“进度”并不是真正相关的,但我希望将它们作为WHERE标准。
Expected Results
----------------------
wsf_ref total
002 195
001 65
答案 0 :(得分:1)
您可以通过将row_number()
与wsf_ref
和type
的分区一起使用来实现。然后在where
中,我指定了应该对哪些记录求和(blue
的前1个和for other types
的前3个)。如果您想按wsf_status
来拟合数据,则可以在cte
中进行修改。
with cte as (
select
*
,ROW_NUMBER() over (partition by wsf_ref, type order by wsf_value desc) as number
from individual
--where wsf_status <your condition>
)
select
wsf_ref
,sum(wsf_value) as total
from cte
where (number <= 3 and type <> 'blue')
or (number = 1 and type = 'blue')
group by wsf_ref
没有row_number()
的解决方案。
select
wsf_ref
,sum(wsf_value) as total
from (select
*,
( select count (*)
from individual u
where
t.wsf_ref = u.wsf_ref and
t.type = u.type and
t.wsf_value <= u.wsf_value
) as number
from individual t) t
where (number <= 3 and type <> 'blue')
or (number = 1 and type = 'blue')
group by wsf_ref
有其他条件(这很丑,因为在此版本的mysql中我们无法使用窗口函数)
select
wsf_ref
,sum(wsf_value) as total
from (select
*,
( select count (*)
from (select * from individual where wsf_status = 'Approved' and wsf_progress IN ('Day 1', 'Day 2', 'Day 3')) u
where
t.wsf_ref = u.wsf_ref and
t.type = u.type and
t.wsf_value <= u.wsf_value
) as number
from (select * from individual where wsf_status = 'Approved' and wsf_progress IN ('Day 1', 'Day 2', 'Day 3')) t) t
where (number <= 3 and type <> 'blue')
or (number = 1 and type = 'blue')
group by wsf_ref