ORDER BY for currency values

左心房为你撑大大i 提交于 2019-12-06 09:37:08

You need two columns:

  • one for the value, a float/double (or an integer) that can be ordered, used in operations such as sums, etc.
  • one for the currency (a char(3) following ISO 4217 standard) used for other purposes (display, maybe conversion, etc.)

Storing both value and symbol inside a varchar is non-sense, especially since the position of the currency symbol varies from country to country (can be at the beginning or at the end), there might be a space between the symbol and the value, or not, etc.

That being said, if you don't want to change your table, something like that could work:

ORDER BY CAST(
  REPLACE(REPLACE(REPLACE(thecolumn,'$',''),'£',''),'₹','')
  AS DECIMAL(10,2)
)

This worked for me...

I created a table with about 15 rows, some containing characters ($,£,€) and some not. I created a calculated field CAST as DECIMAL, then I check the leftmost character to see if it can be cast as a number, if so we check the rightmost character since some currencies put the symbol at the end. If the right character is > 0, we use prize_value, otherwise we take the left characters. Back to the first IF statement, if it wasn't greater than 0 that means it either leads with a 0 (which doesn't matter) or it was a non-number (in this case a monetary symbol), so we take the rightmost text. Finally we close off the CAST field and sort by it. You can put this as a calculated field, or as the ORDER BY. I put it both ways below.

SELECT prize_value,
      CAST(IF(LEFT(test.prize_value,1) IN ('.',','),
             REPLACE(test.prize_value,LEFT(test.prize_value,1),'0.'),
             IF(CAST(LEFT(test.prize_value, 1) AS DECIMAL(10,2)) > 0,
                IF(CAST(RIGHT(test.prize_value, 1) AS DECIMAL(10,2)) > 0,
                  test.prize_value,
                  LEFT(test.prize_value, LENGTH(test.prize_value) - 1)
                ),
                RIGHT(test.prize_value, LENGTH(test.prize_value) - 1)
             )
           )
      AS DECIMAL(10,2)) AS prize_value_only
  FROM chatter.test
ORDER BY prize_value_only ASC

--- OR ---

SELECT prize_value
  FROM chatter.test
ORDER BY 
      CAST(IF(LEFT(test.prize_value,1) IN ('.',','),
             REPLACE(test.prize_value,LEFT(test.prize_value,1),'0.'),
             IF(CAST(LEFT(test.prize_value, 1) AS DECIMAL(10,2)) > 0,
                IF(CAST(RIGHT(test.prize_value, 1) AS DECIMAL(10,2)) > 0,
                  test.prize_value,
                  LEFT(test.prize_value, LENGTH(test.prize_value) - 1)
                ),
                RIGHT(test.prize_value, LENGTH(test.prize_value) - 1)
             )
           ) AS DECIMAL(10,2)) ASC
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!