15

さまざまなファイル サイズをバイト単位で保存するログ テーブルがあります。データベースにクエリを実行し、MB GB などに変換された最小の浮動小数点数を返したいと考えています。現在、MB 単位で値を返すことができますが、さらに最小値に分割して単位を追加するにはどうすればよいですか?

SELECT CONCAT( ROUND( SUM( data_transferred ) /1048576, 2 ) ,  ' MB' ) 
FROM  `logs`

どんな助けでも大歓迎です。

アップデート:

voodoo417 が提供したリンクに基づいて、クエリを次のように更新しました。これにより、最も関連性の高いファイル サイズが小数点以下 2 桁まで出力され、単位 (1000 バイト、1 KB、500 MB、2 GB など) が追加されます。

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
4

5 に答える 5

17

これは古い質問であることは知っていますが、最近同じことを探していたところ、MySQL 5.7 がformat_bytesまさにこの目的のために機能を追加したことがわかりました。

mysql> SELECT format_bytes(512), format_bytes(18446644073709551615);
+-------------------+------------------------------------+
| format_bytes(512) | format_bytes(18446644073709551615) |
+-------------------+------------------------------------+
| 512 bytes         | 16383.91 PiB                       |
+-------------------+------------------------------------+
于 2016-06-10T16:42:47.417 に答える
5

ファイルサイズが 0 の場合、Renaat のコードは失敗します (明らかに、ゼロから LOG を実行することはできません)。したがって、@log は null で埋められ、CONCAT も null を生成します。正しい修正は次のとおりです。

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'));
于 2015-05-15T00:39:28.340 に答える
5

私はより洗練されたソリューションを持っています(ユーザー定義関数も使用しています):

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'));
于 2015-01-19T14:34:48.613 に答える
0

select concat(round(data*1048576/1073741824,2),' GB')

例: 1024 = 1GB select concat(round(1024*1048576/1073741824,2),' GB') 1GB

于 2016-10-22T08:25:57.640 に答える
0

format_bytes2016 年に回答があったにもかかわらず、使用に関するトップの回答は、残念ながらまだ 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が、それは私が目指していたものではありません。

于 2021-03-23T11:46:42.220 に答える