Formatting data type real in Postgres - postgresql

I tried a whole range of patterns with the to_char() function but cannot find the right one.
to_char(price, '99999990D00')
I have two test numbers 0 and 399326, I want 0 to become '0.00' and 399326 to become '399326.00'.
I found out that I needed to add a '9' to my pattern for as many numbers to expect, that is my first concern. When I supply '999999990D99' I get an error message, I suppose this is a too long pattern, but this limits my numbers. This will be a problem. supplying '9990D99' as a pattern to '399326' results in '####.'.
Second of all, I cannot find how to get the two trailing zeros behind the large number, though it works with the '0'. I tried with '999999990D99', '999999990D09' and '999999990D00' but it doesn't seem to work either way.
UPDATE
The solution of Laurenz Albe works with integers, look at my two examples below:
SELECT
to_char(0, '99999999990D00FM'),
to_char(1, '99999999990D00FM'),
to_char(11, '99999999990D00FM'),
to_char(111, '99999999990D00FM'),
to_char(1111, '99999999990D00FM'),
to_char(11111, '99999999990D00FM'),
to_char(111111, '99999999990D00FM'),
to_char(1111111, '99999999990D00FM'),
to_char(11111111, '99999999990D00FM')
WHERE 1=1
outputs:
"0.00"; "1.00"; "11.00"; "111.00"; "1111.00"; "11111.00"; "111111.00"; "1111111.00"; "11111111.00"
As expected.
SELECT
to_char(0::real, '99999999990D00FM'),
to_char(1::real, '99999999990D00FM'),
to_char(11::real, '99999999990D00FM'),
to_char(111::real, '99999999990D00FM'),
to_char(1111::real, '99999999990D00FM'),
to_char(11111::real, '99999999990D00FM'),
to_char(111111::real, '99999999990D00FM'),
to_char(1111111::real, '99999999990D00FM'),
to_char(11111111::real, '99999999990D00FM')
WHERE 1=1
outputs:
"0.00"; "1.00"; "11.00"; "111.00"; "1111.00"; "11111.0"; "111111"; "1111111"; "11111111"
And this is strange, according to the documentation it should work also for the real data type. Is this a bug in Postgres?

Cast the reals to numeric and use the FM modifier:
SELECT to_char((REAL '123456789')::numeric, '99999999990D00FM');
to_char
--------------
123457000,00
(1 row)
This will cut off all positions that exceed real's precision.

Related

Number format equivalent function in PostgreSQL

Trying to format the number as per the given format and culture.
Given:
-4059587.225000, --Value
'#,##0.00;(#,##0.00)' --Format
'en-US' --Culture
Will have many patterns, the given one is for example.
Expected output: (4,059,587.23)
In SQL Server we have format() function, what's the equivalent in PostgreSQL?
My try:
select to_char( -4059587.225000, '#,##0.00;(#,##0.00)' );
Error:
multiple decimal points
Use to_char:
SET lc_numeric = 'en_US';
SELECT translate(to_char(-4059587.225000, '9G999G999D99PRFM'), '<>', '()');
translate
════════════════
(4,059,587.23)
(1 row)
The documentation describes the available formats.
How about:
select
concat( to_char( -4059587.225000, '#,##0.00;' ), to_char( -4059587.225000, '(#,##0.00)' ) );

Arithmetic overflow error converting expression to data type int message in T-SQL code

I have the following code:
SELECT
ehrprg.ReportName
,ehrprg.AnnualGoalServiceMinutes
,COUNT(DISTINCT ct.[ClientFK]) AS [UnduplicatedClients]
FROM
[WH].[Fact].[EHRClinicalTransaction] ct
INNER JOIN [Dimension].EHRProgram ehrprg ON
ct.ProgramFK = ehrprg.WHID
WHERE
ehrprg.AnnualGoalServiceMinutes > 0
GROUP BY
ehrprg.ReportName
,ehrprg.AnnualGoalServiceMinutes
ORDER BY
ReportName
and result:
But I need it would have only one 'SM NV'(instead of 2) and one 'SM REACH' (instead of 3) rows in the [ReportName] column, summarizing [ServiceMinutes]
When I use SUM(ehrprg.AnnualGoalServiceMinutes) it gives me "Arithmetic overflow error converting to datatype int" error.
Then, I tried ,SUM(CONVERT(BIGINT, ehrprg.AnnualGoalServiceMinutes)), but getting the following:
It is still not grouping (not summarizing AnnualGoalServiceMinutes) and gives some values, I can't understand
My goal is to see instead of-
ReportName AnnualGoalServiceMin
SM NV 197885
SM NV 348654
SM REACH 40000
SM REACH 80000
SM REACH 380000
I expect the SUM of the AnnualGoalServiceMin:
ReportName AnnualGoalServiceMin
SM NV 546539
SN REACH 500000
Please, help
I don't know the source of the overflow error (it should not be happening based on the magnitude of the integers invovled), but I think what you need here is a second level of aggregation:
WITH cte AS (
SELECT
ehrprg.ReportName,
ehrprg.AnnualGoalServiceMinutes,
COUNT(DISTINCT ct.[ClientFK]) AS UnduplicatedClients
FROM [WH].[Fact].[EHRClinicalTransaction] ct
INNER JOIN [Dimension].EHRProgram ehrprg
ON ct.ProgramFK = ehrprg.WHID
WHERE ehrprg.AnnualGoalServiceMinutes > 0
GROUP BY ehrprg.ReportName, ehrprg.AnnualGoalServiceMinutes
)
SELECT
ReportName,
SUM(AnnualGoalServiceMinutes) AS AnnualGoalServiceMinutes,
SUM(UnduplicatedClients) AS UnduplicatedClients
FROM cte
GROUP BY
ReportName;

SP/View for daily aggregation of 3-hours values

i'm trying to group 3-hours forecasting values into a daily table, The problem is that i need to process non standard group operations on values. I attach an example (provided by Openweather ).
time temp press desc w_sp w_dir
"2017-12-20 00:00:00" -4.49 1023.42 "clear" 1.21 198.501
"2017-12-20 03:00:00" -2.51 1023.63 "clouds" 1.22 180.501
"2017-12-20 06:00:00" -0.07 1024.43 "clouds" 1.53 169.503
"2017-12-20 09:00:00" 0.57 1024.83 "snow" 1.77 138.502
"2017-12-20 12:00:00" 0.95 1024.41 "snow" 1.61 271.001
"2017-12-20 15:00:00" -0.47 1024.17 "snow" 0.61 27.5019
"2017-12-20 18:00:00" -2.52 1024.52 "clear" 1.16 13.0007
"2017-12-20 21:00:00" -2.63 1024.73 "clear" 1.07 131.504
In my case i should evaluate the overall daily meteo description according to a mix of the top 2 occurence labels, and concerning wind direction i cannot AVG the 8 values, i have to apply a specific formula.
I'm familiar with sql but not so much with postgres stored procedures, i think i need something like cursor but i'm a bit lost here. I'm sure this can be achieved in many ways but i'm asking you to give me the path. So far i have a draft of a stored procedure but i'm a bit clueless
CREATE FUNCTION meteo_forecast_daily ()
RETURNS TABLE (
forecasting_date DATE,
temperature NUMERIC,
pressure NUMERIC,
description VARCHAR(20),
w_speed NUMERIC,
w_dir NUMERIC
)
AS $$
DECLARE
clouds INTEGER;
snow INTEGER;
clear INTEGER;
rain INTEGER;
thunderstorm INTEGER;
BEGIN
RETURN QUERY SELECT
m.forecasting_time::date as forecasting_date,
avg(m.temperature) as temperature
avg(m.pressure) as pressure
description???
avg(m.w_sp) as w_speed
w_dir????
FROM
meteo_forecast_last_update m
WHERE
forecasting_time > now()
group by forecasting_date;
END; $$
LANGUAGE 'plpgsql';
Thus my question is, how can i retrieve the 8 elements for each date and process them somehow separately?
Desired result:
time temp press desc w_sp w_dir
"2017-12-20" -4.49 1023.42 "clear,clouds,rain,..." 1.21 (198.501, 212.23..)
"2017-12-21" -4.49 1023.42 "rain,snow,rain,..." 1.45 (211.501, 112.26..)
"2017-12-22" -4.49 1023.42 "clear,clouds,rain,..." 1.89 (156.501, 312.53..)
Thanks in advance and happy new year :)
You should achieve this by
SELECT m.forecasting_time::date AS forecasting_date,
AVG(m.temperature) as temperature,
AVG(m.pressure) as pressure,
STRING_AGG(DISTINCT m.description, ',') AS description,
AVG(m.w_sp) as w_speed,
ARRAY_AGG(m.w_dir) AS w_dir
FROM meteo_forecast_last_update m
WHERE m.forecasting_time > now()
GROUP BY 1 ORDER BY 1;
You may use DISTINCT inside of an aggregate function. It applies the aggregate function only for distinct values.

Querying with multiple value parameter in SQL Server Report Builder

I am basically trying to do what is asked in this question:
Passing multiple values for a single parameter in Reporting Services
but it is not working for me.
My parameter has a data type of text. I have a feeling that my parameter is being surrounded by quotes when it is inserted into my query.
Query
SELECT
AllUserData.tp_ID, Title as TestSite, tp_Title as TestCase, nvarchar6 as ItemNumber,
nvarchar7 as DefectType, nvarchar8 as Status, nvarchar9 as QuestionID,
ntext2 as Question, AllUserData.tp_Version as Version,
CONVERT(VARCHAR(10), AllUserData.tp_Modified, 111) AS DateModified
FROM
[dbTOG].[dbo].[AllUserData]
INNER JOIN
dbTOG.dbo.AllLists on dbTOG.dbo.AllUserData.tp_ListId = dbTOG.dbo.AllLists.tp_ID
INNER JOIN
dbTOG.dbo.Webs on dbTOG.dbo.AllLists.tp_WebId = dbTOG.dbo.Webs.Id
WHERE
(nvarchar8 = 'PASS' OR
nvarchar8 = 'FAIL' OR
nvarchar8 = 'N/A' OR
nvarchar8 = 'TBD' OR
nvarchar8 = 'TBRT' OR
nvarchar8 = 'FIXED')
AND Title = #TestSite
AND tp_Title IN (#TestCase)
Parameter expression for #TestCase
=Join(Parameters!TestCase.Value, ",")
This is quite late but I was struggling with pretty much the same thing. Eventually I found the answer from the link in the OT, however not the accepted one.
I changed the parameter expression to:
=SPLIT(JOIN(Parameters!<your param name>.Value,","),",")
This worked perfectly for me.

T-SQL not executing 2nd part of WHERE clause SSRS

I have a SSRS report which runs from a stored procedure. I've got 2 parameters that must be chosen. My first parameter works perfectly, but when the 2nd parameter is chosen (Rep) it gets ignored by the report and returns all the Reps.
#Town Varchar(100)
,#Rep Varchar(100)
select
a.Customer
,a.CustName
,a.Rep
,a.Town
,a.Qty
,a.SalesType
,b.Qty1
,c.Qty2
......
from #1 a
left join #2 b
on a.Rep = b.Rep
and a.Town = b.Town
and a.Customer = b.Customer
and a.SalesType = b.SalesType
left join #3 c
..........
WHERE ('ALL' IN (#Town)) OR (a.Town IN (#Town))
and ('ALL' IN (#Rep)) OR (a.Rep IN (#Rep))
Guessing here, but I am assuming you want the clauses for #Town and #Rep to be evaluates as a group each. To do so:
WHERE ('ALL' IN (#Town) OR a.Town IN (#Town))
and ('ALL' IN (#Rep) OR a.Rep IN (#Rep))
As you have it, since each clause is stand alone, you will get short circuit behavior.