PgSQL - Error while executing a select - postgresql

I am trying to write a simple select query in PgSQL but I keep getting an error. I am not sure what I am missing. Any help would be appreciated.
select residuals, residuals/stddev_pop(residuals)
from mySchema.results;
This gives an error
ERROR: column "results.residuals" must appear in the GROUP BY clause or be used in an aggregate function
Residuals is a numeric value (continuous variable)
What am I missing?

stddev_pop is an aggregate function. That means that it takes a set of rows as its input. Your query mentions two values in the SELECT clause:
residuals, this is a value from a single row.
stddev_pop(residuals), this is an aggregate value and represents multiple rows.
You're not telling PostgreSQL how it should choose the singular residuals value to go with the aggregate standard deviation and so PostgreSQL says that residuals
must appear in the GROUP BY clause or be used in an aggregate function
I'm not sure what you're trying to accomplish so I can't tell you how to fix your query. A naive suggestion would be:
select residuals, residuals/stddev_pop(residuals)
from mySchema.results
group by residuals
but that would leave you computing the standard deviation of groups of identical values and that doesn't seem terribly productive (especially when you're going to use the standard deviation as a divisor).
Perhaps you need to revisit the formula you're trying to compute as well as fixing your SQL.
If you want to compute the standard deviation separately and then divide each residuals by that then you'd want something like this:
select residuals,
residuals/(select stddev_pop(residuals) from mySchema.results)
from mySchema.results

Related

How to divide an Aggregate and Sum function

I am working in Tableau and trying to create a formula that will return me the value of each customer that walks into a store by dividing Net Sales / Traffic. When I try to combine the two separate formulas, it gives me the following error: Cannot mix aggregate and non-aggregate arguments with this function. The two functions I created that I'm trying to divide are:
SOT = (SUM([Sales Net])-SUM([Sales Gcard Net]))/SUM([Traffic Perday]) and SOT Goal
When I look at it in Tableau, it's stating that SOT is an aggregate function. How do I work around this to be able to get
SOT / SOT Goal
Aggregate variables are values that are calculated in the view, and depend on the level of aggregation in Tableau. e.g. sum(Sales) will show different values in Tableau if it’s next to a Region dimension, or if it’s next to a Category dimension.
In order to avoid the errors you can use many solutions. My favorite is indeed LOD expressions. In your view, though I do not have required sample data and therefore, I cannot try my hands on different possibilities here, I suggest that this should work-
SOT = ({SUM([Sales Net])}-{SUM([Sales Gcard Net])})/{SUM([Traffic Perday])}
Do remember that this solution will over-ride your filters and if you are using filters you have to add all those to Context.
EDIT
While trying different possibilities remember these things...
{SUM([Sales])} will sum the sales over entire data and {} i.e. curly braces wrapped around the sum function will cause to return the value as non-aggregate. In other words, this will work as LOD and if you'll add this field to view, the sum of entire sales will be shown against each row.
{FIXED [DIMENSION NAME] : sum([Sales])} will sum sales separately for each Dimension value. Fixed statement (LOD) again returns the value as non-aggregate value. if you'll add this field to view, the sum of entire sales for that dimension will be shown against each dimension.

Dividing AVG of column1 by AVG of column2

I am trying to divide the average value of column1 by the average value of column 2, which will give me an average price from my data. I believe there is a problem with my syntax / structure of my code, or I am making a rookie mistake.
I have searched stack and cannot find many examples of dividing two averaged columns, and checked the postgres documentation.
The individual average query is working fine (as shown here)
SELECT (AVG(CAST("Column1" AS numeric(4,2))),2) FROM table1
But when I combine two of them in an attempt to divide, It simply does not work.
SELECT (AVG(CAST("Column1" AS numeric(4,2))),2) / (AVG(CAST("Column2" AS numeric(4,2))),2) FROM table1
I am receiving the following error; "ERROR: row comparison operator must yield type boolean, not type numeric". I have tried a few other variations which have mostly given me syntax errors.
I don't know what you are trying to do with your current approach. However, if you want to take the ratio of two averages, you could also just take the ratio of the sums:
SELECT SUM(CAST(Column1 AS numeric(4,2))) / SUM(CAST(Column2 AS numeric(4,2)))
FROM table1;
Note that SUM() just takes a single input, not two inputs. The reason why we can use the sums is that average would normalize both the numerator and denominator by the same amount, which is the number of rows in table1. Hence, this factor just cancels out.

Tableau, how to calculate Weighted Standard Deviation

I've a problem to calculate weighted standard deviation. Here's the formula I used:
sum([Weight]*(([Variable]-[Mean Score - Variable])^2))
/
SUM([Weight])
But there's a error pop up message "Cannot mix aggregrate and non-aggregrate"
I wonder what's wrong with my formula?
Thanks
I am assuming Variable and Weight are explicit fields in your dataset, while [Mean Score] is a calculated field you defined in Tableau.
[Mean Score] is an aggregate calculation; Variable is not. You can check this by dragging [Mean Score] to any shelf in Tableau, and note that it is show within the prefix AGG(). Note that you can't select the form of aggregation (SUM, MIN, AVG) to apply in that case, because the aggregation function is defined within that calculation.
You can't mix aggregate and record level calculations directly. Record level calculations are evaluated once for each individual data row. Aggregate calculations are evaluated once for each block of data rows.
The dimensions used in your worksheet determine which data rows are grouped together into blocks (partitioning the data). Analogous to the fields that follow the keyword GROUP BY in SQL select statement. As with SQL, the other fields referenced must be aggregated somehow such as via a SUM(), MIN(), MAX() or other call. Tableau calls those fields measures.
The most straightforward solution is to revise your definition of [Mean Score] to make it a Level Of Detail (LOD) calc instead of an aggregate calc.
That will allow you to essentially first compute the mean score separately, and then reference that result in your record level calculation. You will have to decide among 3 different ways for determining the dimensions for your LOD calc. See the online help for more info on LOD calcs.
For example, try replacing [Mean Score] with { include : [Mean Score] }

Differencing a column in a data source

I have a text file with two columns: "date" and "cumulative value". I'd like to difference "cumulative value", as a calculated field in the data source.
I cannot even get a lag value:lookup([cumulative value],-1) produces an error.
Thank you.
There are two things you can do.
Create a new field with the following formula:
SUM([cumulative value])-LOOKUP(SUM([cumulative value]),-1)
Tableau requires an aggregation for you to use the LOOKUP function. Hence why I used the sum function. Then you could plot that against DAY(Date).
OR
Plot DAY(Date) against SUM(cumulative value), then right click SUM(cumulative value), click Quick Table Calculation, and then Difference. This can only be used/done in plots though.

Weighted Average Fields

I'm totally new to doing calculations in T-SQL. I guess I'm wondering what is a weighted average and how do you do it in T-SQL for a field?
First off as far as I know a weighted average is simply just multiplying 2 columns then average it by dividing by something.
Here's an example of a calculated field I have in my view, after calling one of our UDFs. Now this field in my view needs to also be a weighted average....no idea where to start to turn this into a weighted average.
So ultimately this UDF returns the AverageCostG. I call the UDF from my view and so here's the guts of the UDF:
Set #AverageCostG = ((#AvgFullYear_Rent * #Months) +
(#PrevYearRent * #PrevYearMonths))
/ #Term
so in my view I'm calling the UDF above to get back that #AverageCostG
CREATE View MyTestView
AS
select v.*, --TODO: get rid of *, that's just for testing, select actual field names
CalculateAvgRentG(d.GrossNet, d.BaseMonthlyRent, d.ILI, d.Increase, d.Term) as AverageRent_G,
....
from SomeOtherView v
Now I need to make this AverageRent_G calc field in my view also a weighted average somehow...
Do I need to know WHAT they want weighted or is it assumed that hey, it's obvious.. I do not know what I need to know in order to do the weighted average for these guys...like what specs I need if any from them other than this calculation I've created based off the UDF call. I mean do I have to do some crazy select join or something in addition to multiplying 2 fields and dividing by something to average it? How do I know what fields they are to be used int he weighted average and from where? I will openly admit I'm totally new to BI T-SQL development as I'm an ASP.NET MVC C#/Architect dev...and lost to this calculation stuff in T-SQL.
I have tried to research this but just need some basic hand holding the first time through this, my head hurts right now caue I don't know what info I need to obtain from them and then what to do exactly to make that calc field weighted.
They'll have to tell you what the weighting factor is. This is my guess.
SUM([weight] * CalculateAvgRentG(...)) / SUM([weight])