MySQL конвертировать байты в килобайты, мегабайты, гигабайты
У меня есть таблица журналов, которая хранит файлы разных размеров в байтах. Я хочу иметь возможность запрашивать базу данных и возвращать наименьшее возможное число с плавающей запятой, которое было преобразовано в МБ ГБ и т. Д. В настоящее время я могу вернуть значение в МБ, но как мне продолжить деление дальше на наименьшее значение и добавить единицу измерения?
SELECT CONCAT( ROUND( SUM( data_transferred ) /1048576, 2 ) , ' MB' )
FROM `logs`
Любая помощь будет оценена.
ОБНОВИТЬ:
На основе предоставленной ссылки voodoo417 я обновил свой запрос следующим образом, который выведет наиболее релевантный размер файла с двумя десятичными разрядами и добавит единицу измерения (1000 байт, 1 кБ, 500 МБ, 2 ГБ и т. Д.):
SET @bytes := (SELECT SUM(data_transferred) FROM wp_ddownload_statistics);
SELECT
CASE
WHEN ABS(@bytes) < 1024 THEN CONCAT( ROUND( @bytes, 2 ), ' Bytes')
WHEN ABS(@bytes) < 1048576 THEN CONCAT( ROUND( (@bytes/1024), 2 ), ' KB')
WHEN ABS(@bytes) < 1073741824 THEN CONCAT( ROUND( (@bytes/1048576), 2 ), ' MB')
WHEN ABS(@bytes) < 1099511627776 THEN CONCAT( ROUND( (@bytes/1073741824), 2 ), ' GB' )
WHEN ABS(@bytes) < 1125899906842624 THEN CONCAT( ROUND( (@bytes/1099511627776), 2 ), ' TB')
WHEN ABS(@bytes) < 1152921504606846976 THEN CONCAT( ROUND( (@bytes/1125899906842624), 2 ), ' PB' )
WHEN ABS(@bytes) < 1180591620717411303424 THEN CONCAT( ROUND( (@bytes/1152921504606846976) ,2), ' EB' )
WHEN ABS(@bytes) < 1208925819614629174706176 THEN CONCAT( ROUND( (@bytes/1180591620717411303424), 2), ' ZB' )
WHEN ABS(@bytes) < 1237940039285380274899124224 THEN CONCAT( ROUND( (@bytes/1208925819614629174706176), 2), ' YB' )
WHEN ABS(@bytes) < 1267650600228229401496703205376 THEN CONCAT( ROUND( (@bytes/1237940039285380274899124224), 2), ' BB' )
END
5 ответов
Я знаю, что это старый вопрос, но я недавно искал то же самое и обнаружил, что MySQL 5.7 добавил format_bytes
функционировать именно для этой цели:
mysql> SELECT format_bytes(512), format_bytes(18446644073709551615);
+-------------------+------------------------------------+
| format_bytes(512) | format_bytes(18446644073709551615) |
+-------------------+------------------------------------+
| 512 bytes | 16383.91 PiB |
+-------------------+------------------------------------+
У меня есть более элегантное решение (также с использованием определенной пользователем функции):
CREATE FUNCTION `format_filesize`(filesize FLOAT) RETURNS varchar(20) CHARSET utf8
BEGIN
DECLARE n INT DEFAULT 1;
LOOP
IF filesize < 1024 THEN
RETURN concat(round(filesize, 2), ' ', elt(n, 'Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB', 'BB'));
END IF;
SET filesize = filesize / 1024;
SET n = n + 1;
END LOOP;
END
ОБНОВИТЬ:
Еще лучше и может использоваться вне процедур:
SET @filesize = 536870912;
SET @log = IFNULL(TRUNCATE(LOG(1024, @filesize), 0),0);
SELECT CONCAT(ROUND(@filesize / POW(1024, @log), 2), ' ',
ELT(@log + 1, 'Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB', 'BB'));
Код Renaat не работает, когда размер файла равен 0 (очевидно, вы не можете сделать LOG с нуля). Поэтому @log заполняется нулем, а CONCAT также создает ноль. Правильное исправление:
SET @filesize = 536870912;
SET @log = IFNULL(TRUNCATE(LOG(1024, @filesize), 0),0);
SELECT CONCAT(ROUND(@filesize / POW(1024, @log), 2), ' ',
ELT(@log + 1, 'Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB', 'BB'));
Главный ответ об использовании, несмотря на то, что получил ответ в 2016 году, к сожалению, до сих пор не найден в MariaDB.
Я адаптировал запрос отсюда, чтобы сделать функцию, которую я мог бы использовать.
FUNCTION `format_bytes`(val float) RETURNS varchar(20) CHARSET latin1
BEGIN
DECLARE pw smallint;
IF val < 1024 THEN
return CONCAT(val, ' B');
END IF;
SET pw = LEAST(7, FLOOR(LOG(val) / LOG(1024)));
RETURN CONCAT(ROUND(val / POW(1024, pw), 2), ' ', SUBSTR('KMGTPEZY', pw, 1), 'B');
END
>>> SELECT format_bytes(512), format_bytes(18446644073709551615);
+-------------------+------------------------------------+
| format_bytes(512) | format_bytes(18446644073709551615) |
+-------------------+------------------------------------+
| 512 B | 16.00 EB |
+-------------------+------------------------------------+
Можно настроить несколько вещей, чтобы они более точно имитировали MySQL.
format_bytes
, но я не к этому стремился.
select concat(round(data*1048576/1073741824,2),' GB')
например: 1024 = 1 ГБselect concat(round(1024*1048576/1073741824,2),' GB')
1gb