PostgreSQL: Meaning of 'AS f(x)' Clause in SELECT Statement - sql

In a presentation on Window functions made by EDB (https://youtu.be/XO1WnmJs9RI), they start out with what they call the simplest form of a window function as this:
SELECT *
FROM generate_series(1, 10) AS f(x);
What is the meaning of the AS f(x) clause at the end of this statement? I searched the documentation under both the SELECT command and the window function, and cannot find any explanation for this syntax. I know that the AS portion allows us to rename the column, but I am clueless on the f(x) part.

This is simply a table alias that defines the result of generate_series():
The table reference is f.
The column reference is x.
The as is optional (and I leave it out of table aliases).
So, you could write the select as:
select f.x
This is handy when you want to use the value for other purposes, such as calculations and joins.

Related

How to run SQL like EVAL in BigQuery

In BigQuery, I have a query and its result is like:
myQueryValue
select * from 'some path'
I'd like to use it directly in new query.
SELECT someValue
FROM
(
select * from 'some path' <- How can I replace this to myQueryValue?
)
How can I use the result value of some queries like EVAL?
----------------EDITED AT 14th Oct.----------------
Thanks for all answer but I need to explain more what I want.
If I have a 'queryTable' like
col
'select * from tableA'
The result of 'select * from tableA' is
foo
bar
When I only know about 'queryTable', how can I get the this result?
foo
bar
I'd like to refer 'queryTable', and get the final result of its.
You can use sub queries, its a query inside the from clause.
Here is an example code:
SELECT * FROM (SELECT ID FROM CUSTOMERS WHERE SALARY > 4500)
A Subquery or Inner query or a Nested query is a query within another
SQL query and embedded within the WHERE clause.
A subquery is used to return data that will be used in the main query
as a condition to further restrict the data to be retrieved.
Subqueries can be used with the SELECT, INSERT, UPDATE, and DELETE
statements along with the operators like =, <, >, >=, <=, IN, BETWEEN,
etc.
There are a few rules that subqueries must follow −
Subqueries must be enclosed within parentheses.
A subquery can have only one column in the SELECT clause, unless
multiple > >columns are in the main query for the subquery to compare
its selected > >columns.
An ORDER BY command cannot be used in a subquery, although the main
query >can use an ORDER BY. The GROUP BY command can be used to
perform the same >function as the ORDER BY in a subquery.
Subqueries that return more than one row can only be used with
multiple >value operators such as the IN operator.
The SELECT list cannot include any references to values that evaluate
to a >BLOB, ARRAY, CLOB, or NCLOB.
A subquery cannot be immediately enclosed in a set function.
The BETWEEN operator cannot be used with a subquery. However, the
BETWEEN >operator can be used within the subquery.
click here for more information about sub queries.
Below is example of how easy to achieve this
DECLARE myQueryValue STRING;
SET myQueryValue = "select * from your_table";
EXECUTE IMMEDIATE '''
SELECT someValue
FROM ( ''' || myQueryValue || ''' )''';
As you didn't provide additional information I'm going to elaborate my comment.
In comment I've proposed that you can use Declare with Set. Good differences between those two are presented in this stackoverflow thread.
DECLARE does not initialize the variable. When you declare it you declare the variable name, the type, and a default value, which could be an expression.
SET is for initializing the variable you declared previously, and you cannot SET the variable until you DECLARE it.
One of the examples has been provided in #Mikhail Berlyant answer in this thread.
However, more detailed information with more examples are mentioned in GCP Set Reference.
Sets a variable to have the value of the provided expression, or sets multiple variables at the same time based on the result of multiple expressions.
The SET statement may appear anywhere within the body of a script.
This is the easiest way to achieve this.
Another common way you could do this is to use SubQuery/Nested Query, it's also well described in the GCP BigQuery Reference.
In GCP doc you can also find example which uses Set, Declare and subquery:
DECLARE target_word STRING DEFAULT 'methinks';
DECLARE corpus_count, word_count INT64;
SET (corpus_count, word_count) = (
SELECT AS STRUCT COUNT(DISTINCT corpus), SUM(word_count)
FROM `bigquery-public-data`.samples.shakespeare
WHERE LOWER(word) = target_word
);
SELECT
FORMAT('Found %d occurrences of "%s" across %d Shakespeare works',
word_count, target_word, corpus_count) AS result;
Output:
Found 151 occurrences of "methinks" across 38 Shakespeare works

Function which returns type runs multiple times

This is my first question here so sorry if I'm doing something wrong.
I have a function in PostgreSQL which returns a type and I want to display all fields from that type.
At first I was doing the following SQL:
SELECT (FC_FUNCTION(FIELD_A, FIELD_B, FIELD_C)).*
FROM TABLE
But I noticed that it was running way too slow. After checking it looked like it was running the function again for each field the type had. Changing the SQL to the following not only returned the same results, but was way faster:
SELECT (X).*
FROM (SELECT FC_FUNCTION(FIELD_A, FIELD_B, FIELD_C) AS X FROM TABLE) A
Is this the correct way of doing it? It feels to me more of a work around than a solution. Thanks!
This is documented:
[...] these two queries have the same result:
SELECT (myfunc(x)).* FROM some_table;
SELECT (myfunc(x)).a, (myfunc(x)).b, (myfunc(x)).c FROM some_table;
Tip
PostgreSQL handles column expansion by actually transforming the first form into the second. So, in this example, myfunc() would get invoked three times per row with either syntax. If it's an expensive function you may wish to avoid that, which you can do with a query like:
SELECT m.* FROM some_table, LATERAL myfunc(x) AS m;
Placing the function in a LATERAL FROM item keeps it from being invoked more than once per row. m.* is still expanded into m.a, m.b, m.c, but now those variables are just references to the output of the FROM item. (The LATERAL keyword is optional here, but we show it to clarify that the function is getting x from some_table.)

How to cast entity to set in PostgreSQL

Using Postgres 9.3, I found out that I can perform something like this:
SELECT generate_series(1,10);
But I can't do this:
SELECT (SELECT generate_series(1,10));
Can I somehow cast SELECT result to setof int to use it same as result from generate_series()?
What exactly is happening there why I can use result from function but not from SELECT?
Your first form is a non-standard feature of Postgres. It allows SRF (Set Returning Functions) in the SELECT list, which are expanded to multiple rows:
Is there something like a zip() function in PostgreSQL that combines two arrays?
Note: that's working for functions, not for sub-selects. That's why your second SELECT is simply invalid syntax.
Standard SQL does not have a provision for that at all, so the feature is frowned upon by some and clean alternatives have been provided (thanks to improvements in the SQL standard). It is largely superseded by the LATERAL feature in Postgres 9.3+:
What is the difference between LATERAL and a subquery in PostgreSQL?
The simple form can be replaced by:
SELECT g
FROM generate_series(1,10) g;
Whenever possible move SRF to the FROM clause and treat them like tables - since version 9.3 that's almost always possible.
Note that g serves as table and column alias automatically in the example. g in SELECT g binds to a column name first. More explicit syntax:
SELECT g
FROM generate_series(1,10) AS t(g); -- table_alias(column_alias)
You need to understand the difference between a row, a set of rows (~ a table) and an array. This would give you an array of integer:
SELECT ARRAY(SELECT g FROM generate_series(1,10) g) AS g_arr;
Browse the tags generate-series and set-returning-functions for many related answers with code examples.

Can SQL SUM() function take an expression as argument?

I'm using SQLite database and I'm wondering whether I'm allowed to write queries as follows:
SELECT SUM(column1 * column2)
FROM my_table;
I googled but references say that SUM function is has the following format:
SUM([DISTINCT|ALL] column)
And my question is: does column mean actually column or does it allow expressions (like above) too?
You can always use a table expression:
SELECT SUM(Calc)
FROM (
SELECT Column1 * Column2 AS 'Calc'
FROM My_Table) t
I don't have SQLite but checking the docs indicates this should work fine.
Yes, you can use an expression like the one you mentioned, if the datatype of both columns allow it.

Using an Alias column in the where clause in ms-sql 2000

I know you cannot use a alias column in the where clause for T-SQL; however, has Microsoft provided some kind of workaround for this?
Related Questions:
Unknown Column In Where Clause
Can you use an alias in the WHERE clause in mysql?
“Invalid column name” error on SQL statement from OpenQuery results
One workaround would be to use a derived table.
For example:
select *
from
(
select a + b as aliased_column
from table
) dt
where dt.aliased_column = something.
I hope this helps.
Depending on what you are aliasing, you could turn it into a user defined function and reference that in both places. Otherwise your copying the aliased code in several places, which tends to become very ugly and means updating 3+ spots if you are also ordering on that column.