我尝试在多个相似列中获取*usedpc
值列表,并order desc
以获取最严重的违规者。此外,我只需要为每个sys_id
选择最近时间戳的值。
示例数据:
Sys_id | timestamp | disk0_usedpc | disk1_usedpc | disk2_usedpc
---
1 | 2016-05-06 15:24:10 | 75 | 45 | 35
1 | 2016-04-06 15:24:10 | 70 | 40 | 30
2 | 2016-05-06 15:24:10 | 23 | 28 | 32
3 | 2016-05-06 15:24:10 | 50 | 51 | 55
期望的结果(例如假设为limit 2
):
1 | 2016-05-06 15:24:10 | disk0_usedpc | 75
3 | 2016-05-06 15:24:10 | disk2_usedpc | 55
我知道我可以使用greatest
,max
和组时间戳来获取每列的最大值,以便只获取最新值,但我无法弄清楚如何获得整个有序值列表(不仅是每列的最大/最大值,而是所有3个磁盘列中的" 5个最高值")。
编辑:我设置了一个SQLFiddle页面: http://sqlfiddle.com/#!9/82202/1/0
EDIT2:我很抱歉延误。我能够让所有三种解决方案都能正常工作,谢谢。如果@PetSerAl可以将他的解决方案放在一个答案中,我会将其标记为已接受,因为此解决方案使我能够非常顺利地进行自定义。
答案 0 :(得分:1)
也许这样的东西会起作用......我知道它可能看起来很冗余,但它可以节省因为对同一个表进行多次连接而导致的开销:
SELECT md.Sys_id,
md.timestamp,
CASE
WHEN
md.disk0_usedpc > md.disk1_usedpc
AND
md.disk0_usedpc > md.disk2_usedpc
THEN 'disk0_usedpc'
WHEN
md.disk1_usedpc > md.disk0_usedpc
AND
md.disk1_usedpc > md.disk2_usedpc
THEN 'disk1_usedpc'
ELSE 'disk2_usedpc'
END AS pcname,
CASE
WHEN
md.disk0_usedpc > md.disk1_usedpc
AND
md.disk0_usedpc > md.disk2_usedpc
THEN md.disk0_usedpc
WHEN
md.disk1_usedpc > md.disk0_usedpc
AND
md.disk1_usedpc > md.disk2_usedpc
THEN md.disk1_usedpc
ELSE md.disk2_usedpc
END AS pcusage
FROM mydatabase md
GROUP BY md.Sys_id HAVING MAX(md.timestamp)
ORDER BY pcusage DESC
答案 1 :(得分:1)
试试这个:
select
t1.sys_id, t1.`timestamp`,
case locate(greatest(disk0_usedpc ,disk1_usedpc ,disk2_usedpc), concat_ws(',' ,disk0_usedpc ,disk1_usedpc ,disk2_usedpc))
when 1 then 'disk0_usedpc'
when 1 + length(concat(disk0_usedpc, ',')) then 'disk1_usedpc'
when 1 + length(concat(disk0_usedpc, ',', disk1_usedpc, ',')) then 'disk2_usedpc'
end as usedpc,
greatest(disk0_usedpc ,disk1_usedpc ,disk2_usedpc) as amount
from yourtable t1
join (
select max(`timestamp`) as `timestamp`, sys_id
from yourtable
group by sys_id
) t2 on t1.sys_id = t2.sys_id and t1.`timestamp` = t2.`timestamp`
order by t1.`timestamp` desc
-- limit 2
如何工作,这里的子查询是尝试获取每个组sys_id
的最新行,作为许多解决方案中的一种方式。然后,您应该在disk0_usedpc ,disk1_usedpc ,disk2_usedpc
中获得最佳列,正如您在问题中所写,函数greatest
是计划。因此greatest(disk0_usedpc ,disk1_usedpc ,disk2_usedpc) as amount
可以帮助您获得金额。
但是你也想要这个列的名称,我在这里使用locate
和concat
,concat_ws
(这避免编写这么多的分隔符,这里是逗号{{1} })。
我们以行
,
1 | 2016-05-06 15:24:10 | 75 | 45 | 35
会给我们" 75,45,35 ",此处此字符串中的75个索引是1,45是4,35是7。
如您所见,concat_ws(',' ,disk0_usedpc ,disk1_usedpc ,disk2_usedpc)
将返回1,因此最大的行为locate(greatest(disk0_usedpc ,disk1_usedpc ,disk2_usedpc), concat_ws(',' ,disk0_usedpc ,disk1_usedpc ,disk2_usedpc))
,此处为此。
答案 2 :(得分:1)
您可以将vm_disk
表连接到三个行表,为每个磁盘创建单独的行。然后,由于现在每个磁盘都有行,您可以轻松地对它们进行过滤或排序。
select
`sys_id`,
`timestamp`,
concat('disk', `disk`, '_usedpc') as `name`,
case `disk`
when 0 then `disk0_usedpc`
when 1 then `disk1_usedpc`
when 2 then `disk2_usedpc`
end as `usedpc`
from
`vm_disk` join
(
select 0 as `disk`
union all
select 1
union all
select 2
) as `t`
where
(`sys_id`, `timestamp`) in (
select
`sys_id`,
max(`timestamp`)
from `vm_disk`
group by `sys_id`
)
order by `usedpc` desc
limit 5