SQL Server Converting bytes to kilobytes/megabytes

ldioqlga  于 2023-04-19  发布在  其他
关注(0)|答案(4)|浏览(135)

I have an attachments table that stores the size of the document in Bytes.

I'm needing to display a result set of all documents in either KB or MB. In KB if the document is less than 1MB or in MB if the document is larger than 1MB.

At the moment I have this within my query, but I'm struggling to get the display properly formatted in terms of rounding.

CASE WHEN D.DocumentSize < 1000000 THEN
        CONCAT(D.DocumentSize / 1024, 'KB')
    ELSE
        CONCAT(D.DocumentSize / 1048576, 'MB')
    END AS DocumentSizeText,

Here are some example values:

87336
1458250
346
8434
8434

346 bytes is going to display 0KB also, so ideally displaying 1KB would be ideal as a minimum.

pftdvrlh

pftdvrlh1#

Use FORMAT if you want to have a specified significant number of decimal values in MB. N3 here is for showing 3 decimal numbers.

(CASE WHEN D.DocumentSize < 1000000 THEN
           CONCAT(CEILING(D.DocumentSize / 1024.0), 'KB')
      ELSE 
           CONCAT(FORMAT(D.DocumentSize / 1048576.0, 'N3'), 'MB')
 END) AS DocumentSizeText
hgc7kmma

hgc7kmma2#

How do you want to round the values? If you want to round up, use ceiling() :

(CASE WHEN D.DocumentSize < 1000000 THEN
           CONCAT(CEILING(D.DocumentSize / 1024.0), 'KB')
      ELSE CONCAT(CEILING(D.DocumentSize / 1048576.0), 'MB')
 END) AS DocumentSizeText,
ghhaqwfi

ghhaqwfi3#

In the original question, it suggested the values should be rounded up when it said
346 bytes is going to display 0KB also, so ideally displaying 1KB would be ideal as a minimum

However clarification comments against an answer suggest that decimal values should be shown, rather than rounding:

It displays 2MB though for 1458250 when it should be 1.45MB

Further, the question said

I'm needing to display a result set ... in KB if the document is less than 1MB or in MB if the document is larger than 1MB

However the suggested answer posed in the question looked at splitting the data on 1000000 bytes, which is really only an approximation of 1 megabyte and all prior answers followed that lead. Funnily enough, when formatting the data, the exact value of a megabyte is used: 1048576.

I'll provide three answers below -

  • one that rounds up, as implied in the question
  • one that provides decimal values, as implied in the comments
  • one that rounds properly (up or down)

I'll extend the answer to show Gigabytes too (even though the question doesn't ask for it - just remove that clause if it is not required, but I think readers may find this extended definition helpful). In both cases I'll use the accurate definitions of megabyte and gigabyte. Full credit goes to the earlier answers which actually solved the initial problem.

Rounding up to nearest value

If dealing with file size, this is being conservative and counting more bytes than is actually being reported.

case 
    when D.DocumentSize < 1048576 then concat(ceiling(D.DocumentSize / 1024.0), ' KB')
    when D.DocumentSize < 1073741824 then concat(ceiling(D.DocumentSize / 1048576.0), ' MB')
    else concat(ceiling(D.DocumentSize / 1073741824.0), ' GB')
end as [DocumentSizeText Rounded Up]

Showing 3 decimal values

Perhaps more accurate, and less readable.

case 
    when D.DocumentSize < 1048576 then concat(format(D.DocumentSize / 1024.0, 'N3'), ' KB')
    when D.DocumentSize < 1073741824 then concat(format(D.DocumentSize / 1048576.0, 'N3'), ' MB')
    else concat(format(D.DocumentSize / 1073741824.0, 'N3'), ' GB')
end as [DocumentSizeText With Decimals]

Rounding properly (up or down)

More accurate than rounding up ... when summing multiple values.

case
    when D.DocumentSize < 1048576 then concat(format(D.DocumentSize / 1024.0, 'N0'), ' KB')
    when D.DocumentSize < 1073741824 then concat(format(D.DocumentSize / 1048576.0, 'N0'), ' MB')
    else concat(format(D.DocumentSize / 1073741824.0, 'N0'), ' GB')
end as [DocumentSizeText Rounded Proper]
tez616oj

tez616oj4#

TRIM((SELECT TOP (1) 
         STR (@Bytes/(POWER(CAST(1024 AS BIGINT), o-1)*1.0), 8, 2) + SPACE(1) + p
  FROM   ( VALUES (1, 'B'), (2, 'KB'), (3, 'MB'), (4, 'GB'), (5, 'TB') )_u(o, p)
  WHERE  @Bytes < POWER(CAST(1024 AS BIGINT), o)
  ORDER BY o )) [Size],

相关问题