pass value from With..as into a function (POSTGRESQL) - postgresql

In Postgresql, I am trying to pass the result of a query into a function but I am getting
SQL Error [42703]: ERROR: column "pakito" does not exist Position:
176
WITH pakito AS(
select array(select job_id from job)
),
updating_job AS(
select internal_update_job_progress('xavier-tenant', pakito)
)
select * from pakito
Anyone has any idea why it wouldn't work and how to make it work?
Thanks!

You forgot FROM pakito in the second CTE.

Related

Hive ParseException: cannot recognize input near 'create' 'table'

I am trying to conduct a hive query of the form
with (
select a,b from some_db.some_table
) as my_subquery
create table some_other_db.new_table as select * from my_subquery
And I am getting the error
cannot recognize input near 'create' 'table' 'some_other_db' in statement
How do I resolve?
The issue is in hive you cannot include create statements after a with statement. They need to be before.
The following query worked:
create table some_other_db.new_table as
with (
select a,b from some_db.some_table
) as my_subquery
select * from my_subquery

How to return an array of table records in PostgreSQL

I am getting a type mismatch error when trying to return an array of elements of type table1, the inherent type of the table1 I have declared.
Error occurred during SQL query execution
Razón:
SQL Error [42P13]: ERROR: return type mismatch in function declared to return table1[]
Detail: Actual return type is record[].
Where: SQL function "arrayof_records"
This is an oversimplified code that reproduces my problem.
drop table if exists table1 cascade;
create table table1 (
id serial primary key,
title text,
create_dt timestamp default now()
);
insert into table1 (title) values
('one'),
('two'),
('three');
create or replace function arrayof_records ()
returns table1[]
stable language sql as $$
select array_agg (t.*)
from (
select * from table1
order by create_dt desc
) as t;
$$;
It is clear that the parser is expecting some other expression in the array_agg function. I have tried t, t.* and *. All of them fail.
I expect there is a syntax, as PostgreSQL 12 documentations states "array_agg(expression)|any non-array type".
Any idea?
You can use a slightly different way of creating the array:
create or replace function arrayof_records ()
returns table1[]
stable language sql
as
$$
select array(
select table1
from table1
order by create_dt desc
);
$$;
That's typically faster than array_agg() as well.

postgresql WITH statement doesn't find auxiliary statements

I have this query:
WITH words_not AS (
SELECT keywords.id
FROM keywords
WHERE keyword = any(array['writing'])
),actes_not AS (
SELECT actes_keywords.acte_id
FROM actes_keywords
WHERE actes_keywords.keyword_id IN (words_not)
)
SELECT actes.id,
actes.acte_date
FROM actes
WHERE actes.id <> all(actes_not);
This returns the following error:
ERROR: column "words_no" does not exist
LINE 1: ...ctes_keywords WHERE actes_keywords.keyword_id IN (mots_non))...
Each auxiliary statement in the WITH query is good (tested) and I thought I was staying pretty close to the manual: https://www.postgresql.org/docs/current/static/queries-with.html
I don't see why the auxiliary statement in the WITH query is not recognised.
You can't use a table reference in an IN (..) clause. You need a sub-query:
WITH words_not AS (
SELECT keywords.id
FROM keywords
WHERE keyword = any(array['writing'])
), actes_not AS (
SELECT actes_keywords.acte_id
FROM actes_keywords
WHERE actes_keywords.keyword_id IN (select id from words_not) --<< HERE
)
SELECT actes.id,
actes.acte_date
FROM actes
WHERE actes.id <> all(select id from actes_not); --<< HERE

Calling a function on every row returned by a subquery

I need to run the following query to extract the values of my raster records in a specific point.
select st_value((select rast from mytable),
(select st_GeomFromText('POINT(30.424 -1.978)', 4326)))
But I encounter with the following error:
ERROR: more than one row returned by a subquery used as an expression
SQL state: 21000
It needs just one record for this function but I need to extract values of all of records.
If a subquery returns multiple rows, you must either use it in a common table expression (CTE / WITH query) and FROM alias, or use FROM (SELECT ...) alias. In this case, though, it looks like it's simpler than that:
select st_value(rast, st_GeomFromText('POINT(30.424 -1.978)', 4326))
FROM mytable;
Both subqueries appear to be unnecessary.
If you truly needed the subquery you'd write something syntactically like:
WITH sq(rast) AS ( SELECT rast FROM mytable )
SELECT st_value(rast, st_GeomFromText('POINT(30.424 -1.978)', 4326))
FROM sq;
or
SELECT st_value(rast, st_GeomFromText('POINT(30.424 -1.978)', 4326))
FROM (SELECT rast FROM mytable) sq(rast);
Try:
Select st_value(rast),
st_GeomFromText('POINT(30.424 -1.978)', 4326)
from mytable
If you have a function with multiple columns, you can do something like this
SELECT (info).column1, (info).column2, (info).column3
FROM (select st_value(rast, st_GeomFromText('POINT(30.424 -1.978)', 4326)) AS info
FROM mytable
) AS foo

T-SQL Why can I reffer only once to temporary object?

with tmp_rows as
(
select * from [dbo].[customer]
)
select * from tmp_rows;
select count(*) from tmp_rows;
I can't get the count of the tmp_rows because I get the error: Invalid object name 'tmp_rows'
If I comment the "select *" query everything is OK
I need to select all rows and then get their count, how to do that ?
with tmp_rows as
(
select * from [dbo].[customer]
)
select * from tmp_rows;
select ##rowcount;
By declaring you statement in using with you are declaring a CTE - further information on CTE's can be found here
A temporary object created using the with keyword can only be used once. You can create a temporary table if you want to use it more than once:
select *
into #tmp_tows
from dbo.customer
select * from #tmp_rows
select count(*) from #tmp_rows
drop table #tmp_rows
This works even if you want to do something different with the result twice, for example getting the count before the result.
The CTE starting with WITH ends with the semicolon ; .
But you can have more than 1 CTE in a WITH statement:
with tmp_rows as
(
select * from [dbo].customer
),
count_rows as
(
select COUNT(*) count_rows from tmp_rows
)
select * from count_rows, tmp_rows;
tmp_rows is a Common Table Expression (CTE), and CTEs are scoped at the statement level:
-- 1st statement, works fine.
with tmp_rows as (select * from [dbo].[customer])
select * from tmp_rows;
-- 2nd statement, returns an error, since tmp_rows is out of scope.
select count(*) from tmp_rows;
By the time your second statement executes, tmp_rows is already out of scope.
Be aware that CTEs are like locally-scoped views, not tables. The result set is never materialized. If you need to materialize a result set, use a local temporary table or table variable instead.