SQL use FORMAT() on a SUM() - mysql

I want to use FORMAT on SUM to produce a currency style format with commas and no decimal places. I'm trying the following using MySQL 5.7:
SELECT FORMAT(SUM(x.07_17 / fx.07_17), 0) AS total.....
The problem is this changes the data drastically. Without the format, I get the correct result of SUM 350914 but with the format, in place, I get 350, so just the first 3 numbers.
What is it I'm doing wrong?

You can check the documentation to see how each parameters works for the FORMAT function https://dev.mysql.com/doc/refman/5.5/en/string-functions.html#function_format
This query shows you different style to display your data (Sql fiddle example)
SELECT SUM(c1 / c2) AS total1
, CONCAT(FORMAT(SUM(c1 / c2), 3, 'fr_FR'), ' €') AS total2
, CONCAT('$', FORMAT(SUM(c1 / c2), 3)) total3
FROM ( SELECT 148277 c1
, 5.1561 c2 ) t

Related

How to assign number data type to new column using SQL SELECT

I am generating a query table using SQL SELECT as below. This formats the numbers in the column 'Free Cashflow (USD mm)' with 2 digits, but the resulting column data type is 'text'.
How can I instead assign a number data type, e.g. 'float' with 2 digits, to the new column 'Free Cashflow (USD mm)' ?
SELECT
(format(("fcf" / "fxusd") / 1000000, 2) as 'Free Cashflow (USD mm)'
FROM "SF1"
You can CAST it to DECIMAL. Note that for values >= 1000, FORMAT will insert a , in the result, which will prevent the CAST from working correctly. Since FORMAT effectively just ROUNDs the value to the given number of decimal places, you can use ROUND instead to resolve that problem:
SELECT
CAST(ROUND(("fcf" / "fxusd") / 1000000, 2) AS DECIMAL(9,2)) as 'Free Cashflow (USD mm)'
FROM "SF1"
Demo on dbfiddle

how to show decimals in sql instead of 0

I am trying to get the percent and it just shows up as zero. I want to show two decimal places such as 0.65
Here is a piece of the query I am selecting:
select count(numbers)/count(othernumbers) decimal(3,2) as"rate"
if I use this it shows up as 0 and gets rid of the rest
select count(numbers)/count(othernumbers) as"rate"
need to convert both of your "count(numbers)" and "count(othernumbers)" to decimal also.
select convert(decimal(5,2), count(numbers))
/
convert(decimal(5,2), count(othernumbers))
as"rate"
Here's an example that works in SSMS (Sql Server):
select Convert(decimal(3,2), convert(decimal(4,2), 1.0) / convert(decimal(4,2), 10.0)) as [rate]
You have to use this convert value to Decimal, This will give you the decimal till two places
SELECT CONVERT( DECIMAL(10,2),
( CONVERT(DECIMAL(10,2), numbers) /
CONVERT(DECIMAL(10,2), othernumbers) ) ) AS rate
SELECT FORMAT(this / that, 2) as rate
Meanwhile, I question whether COUNT(numbers) is what you want. That counts how many rows have a non-NULL value in the column numbers.
Also, fraction is usually more like x / (x+y) -- meaning the fraction of the total (x+y) that is x.
A "percentage" needs 100* somewhere. 13/20 is the fraction 0.65 or the percentage 65.00 .
Have you checked ceil(), floor() and round()
If you want without rounding anything
SELECT TRUNCATE(count(numbers)/count(othernumbers),2) as "rate"
http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_truncate
select convert(decimal(11, 2), 102)
select convert(decimal(11, 2), 102.5)
select convert(decimal(11, 2), 102.74)
select convert(decimal(11, 2), 102.745)
Results:
102.00;
102.50;
102.74;
102.75

MySQL Sorting when using FORMAT function

I have a query that SUMS different values and then orders the results using ORDER BY.
Whenever I format the result using FORMAT I get a different ordering than without format.
For example:
Ordering without format: 2827.0000, 1668.0000, 663.1000
Ordering with format: 663.10, 2,827.00, 1,668.00
What could be causing this behaviour?
This is the full query:
SELECT
FORMAT( ( (Sum(CASE WHEN YEAR(order_date) = 2015 THEN total END) / 100) - (SELECT COALESCE( ( SUM(total) / 100), 0)
FROM returns WHERE customer = orders.customer AND YEAR(return_dat) = 2015) ), 2) AS anual
FROM orders
WHERE 1 GROUP BY customer ORDER BY anual DESC
Ordering formatted strings is going to result in ASCII-abetical sorting. If you want them sorted numerically, you'll need to have two columns, formatted and unformatted. Keep in mind this is usually best done in your application layer.

Query to Select where timestamp between date1 and date 2

I have MySQL table
id product p_image
1 G images\20131030164545.jpg
2 S images\20131230164545.jpg
3 V images\20140110164545.jpg
4 R images\20140320164545.jpg
5 K images\20140526164545.jpg
6 L images\20150110164545.jpg
7 SK images\20150120164545.jpg
Here I need to extract products from above table where p_image timestamp between two dates (for example I need to extract from 2013/12/01 to 2014/07/30 dates)
In this query I need to extract timestamp from this string 'images\20140526164545.jpg' and convert this to date format and select values between two dates.
Assuming the format of the string is fixed (which it looks to be) you can use thesubstrfunction to extract the timestamp and then cast it to a date and filter by it. Something like this should work:
select * from table1
where cast(substr(p_image FROM 7 FOR 14) as date)
between '2013/12/01' and '2014/07/30'
Sample SQL Fiddle
There might be more efficient ways to do this, but this should give you an idea to start with.
Edit: if the string can vary the something like left(right(p_image, 18), 14) should work.
The dates in p_image are in YYYYMMDD format, so you can compare them as strings. That is, there is no reason to convert the strings to a date data type.
Hence you can just do:
where substr(p_image, 8, 8) between '20131201' and '20140730'
If the position of the date is not fixed but always after the /, you can do:
where left(substring_index(p_image, '/', -1), 8) between '20131201' and '20140730'
Try this it will working :
select * from `datetest` where substr(p_image, 8, 8) between '20131201' and '20140730'
Screenshot of Phpmyadmin :

Is any way to convert decimal to time in MySQL?

I created a field called 'hours_spent' in MySQL using the decimal datatype to store time. The values are stored like this 1.30, 2.30 etc... (for 1hr30min, 2hr30min).
I want to calculate the sum of various time values.
The sum of time is not what I expected: 1.30 + 2.30 = 3.60, whereas I expected 4.00.
I used the SUM function in MySQL to count the hours_spent field. If the values are 0.30 + 1.50 = 1.80, whereas I expected 2.20.
My first mistake was to use the decimal type instead of the time datatype, but I cannot change datatype.
So, is there any way to sum the time values and get result as I expect?
Thanks
I prepared you a demo at sqlfiddle, you can try it there if you want:
http://www.sqlfiddle.com/#!2/c9afc/2
Here are the query samples:
select #indexer:=instr(dateasdecimal, '.')
, left(dateasdecimal, #indexer-1) * 60 + substr(dateasdecimal, #indexer+1) as totalMinutes
from testtable;
select #indexer:=instr(dateasdecimal, '.')
, sum(left(dateasdecimal, #indexer-1) * 60 + substr(dateasdecimal, #indexer+1)) as totalMinutes
from testtable;
Note: Please don't forget to accept answers to your questions:
https://meta.stackexchange.com/a/65088/200585
To convert a decimal into seconds, you could use this:
truncate(hours_spent,0)*60+(hours_spent-truncate(hours_spent,0))*100
and then you can do the sums easily. Then you can convert back seconds to the decimal format with this:
truncate(seconds/60,0)+truncate(mod(seconds, 60)/100,2)
You could always turn the decimals into a string, cast as time, then sum that time using time_to_sec and produce a formatted time with sec_to_time. Of course, it would be much better to be storing those times a different way, even if it involves converting the entire dataset.
SELECT sec_to_time(sum(time_to_sec(goodTime))) FROM (
SELECT CAST(badTime AS TIME) AS goodTime FROM (
SELECT REPLACE(badTime, '.', ':') AS badTime FROM (
SELECT CAST(badTime AS dec(4,2)) AS badTime FROM (
SELECT 1.3 AS badTime
UNION select 2.3
) z
) y
) x
) w