postgres WITH query claims no FROM-clause - postgresql

I've written a simple query that uses a WITH clause, but I'm getting this error:
Error : ERROR: missing FROM-clause entry for table "cte"
Here's the query, where I'm clearly putting a FROM clause. I know this must be simple but I'm just not seeing what I've done wrong. Thanks.
WITH cte AS (
SELECT cident, "month"
FROM orders_extended io
WHERE io.ident = 1 -- 1 will be replaced with a function parameter
)
SELECT *
FROM orders_extended o
WHERE o.cident = cte.cident AND o."month" = cte."month"
ORDER BY o."month" DESC, o.cname

The message didn't lie.
WITH cte AS (
SELECT cident, "month"
FROM orders_extended io
WHERE io.ident = 1 -- 1 will be replaced with a function parameter
)
SELECT o.*
FROM orders_extended o
INNER JOIN cte ON (o.cident = cte.cident and o."month" = cte."month")
ORDER BY o."month" DESC, o.cname

Related

Knex query error undefined column using nested select with orderBy

In a Knex query I'm getting that a column is undefined and I don't know how to resolve
the query I have in Knex
this.builder.orderBy(
this.tx(messageTable)
.max(messageColumns.createdAt)
.where(messageColumns.conversationId, 'conversation.id')
, direction)
The undefined happen on the last part of the .where(messageColumns.conversationId, 'conversation.id')
the SQL I want to get it to work with Knex is as follow
SELECT
*
FROM
"conversation"
ORDER BY
(
SELECT
max("created_at")
FROM
"message"
WHERE
"conversation_id" = conversation.id)
DESC
The query is wrong , try to do this:
select c.* from conversation c
join (
select conversation_id, max("created_at") created_at
from message
group by conversation_id
) m on c.conversation_id = m.conversation_id
order by m.created_at DESC

Postgres “missing FROM-clause entry” error on distinct select query

Below error is generated while creating a inner join on 2 tables in PostgreSQL with distinct clause.Here is my query :
select distinct public."firstapp_offer_Vendor".user_id from
(SELECT
public.firstapp_bid.id,
public.firstapp_bid."Bid",
public.firstapp_bid.offer_id,
public."firstapp_offer_Vendor".user_id,
public."firstapp_offer_Vendor".offer_id
FROM
public.firstapp_bid
inner JOIN public."firstapp_offer_Vendor"
ON public."firstapp_offer_Vendor".offer_id = public.firstapp_bid.offer_id) as foo;
but as i execute it,this error is generated.Please help.
ERROR: syntax error at or near "."
LINE 11: ...r".offer_id = public.firstapp_bid.offer_id) public."firstapp...
try this
select distinct user_id from
(SELECT
fb.id,
fb.Bid,
fb.offer_id,
fov.user_id,
fov.offer_id
FROM
public.firstapp_bid as fb
inner JOIN public.firstapp_offer_Vendor as fov
ON fov.offer_id = fb.offer_id) as foo;

Why is my postgres lateral subquery failing?

I'm trying to run the following query with postgres's support for LATERAL subqueries:
with s as
(
select
tagValues ->> 'mode' as metric
, array_agg(id) as ids
from
metric_v3.v_series
where
name = 'node_cpu'
group by 1
)
select
t.starttime
, s.metric
, t.max
from
s, lateral (
select
d.starttime
, max(d.max) as max
from
metric_v3.gaugedata d
where
d.starttime >= '2020-01-17T00:00Z' AND d.starttime < '2020-01-24T00:00Z'
and d.seriesid in s.ids
group by 1
) t
order by 1,2;
It fails with, where s relates to the reference in the lateral subquery's where clause.
SQL Error [42601]: ERROR: syntax error at or near "s"
I have tried different methods for the lateral query, but I always get the same error. I don't know what I'm missing.
If I run the CTE expression and select s.* from it, I get the expected results, so that part is working fine.
I'm running Postgres 11.6 on CentOS.
You can't use IN with an array. You need to use the ANY operator:
and d.seriesid = any(s.ids)

Syntax error at or near "USING"

I am trying to recreate the functionality of a query found inside of a mapfile on our mapserver into a plpgsql stored procedure.
Here is the query:
geom from (select g.gid, g.geom, g.basin, a.\"DATE\", a.\"VALUE\" from sarffg_basins_00_regional_3sec as g join \"%prod_table%\" as a on g.basin = a.\"BASIN\" where a.\"DATE\" = '%prod_date%') as subquery using unique gid using srid=4326
Within my stored procedure, I have:
RETURN QUERY
EXECUTE 'SELECT geom FROM (
SELECT g.gid,
g.geom,
g.basin,
a.date,
a.value
FROM sarffg_basins_00_regional_3sec AS g
JOIN '||tablename_ts||' AS a
ON g.basin = a.basin
WHERE a.date = '''||adj_timestamp||''')
AS subquery USING UNIQUE gid USING srid=4326';
The above query found within my mapfile works fine. When I try calling my stored procedure inside of psql, I get:
ERROR: syntax error at or near "USING"
LINE 11: AS subquery USING UNIQUE gid USING srid=4326
^
QUERY: SELECT geom FROM (
SELECT g.gid,
g.geom,
g.basin,
a.date,
a.value
FROM sarffg_basins_00_regional_3sec AS g
JOIN temp_table_ts AS a
ON g.basin = a.basin
WHERE a.date = '2017-01-15 00:00:00+00')
AS subquery USING UNIQUE gid USING srid=4326
CONTEXT: PL/pgSQL function ingest_ffgs_prod_composite_csv(text,bigint,boolean,boolean) line 239 at RETURN QUERY
I have also tried omitting the "using" clause within my function and instead leaving that part within the mapfile after my stored procedure is called, i.e.:
DATA "select * from ingest_ffgs_prod_composite_csv('%prod_table%', 1484438400) as subquery using unique gid using srid=4326"
With the stored procedure containing:
RETURN QUERY
EXECUTE 'SELECT geom FROM (
SELECT g.gid,
g.geom,
g.basin,
a.date,
a.value
FROM sarffg_basins_00_regional_3sec AS g
JOIN '||tablename_ts||' AS a
ON g.basin = a.basin
WHERE a.date = '''||adj_timestamp||''');
But this leaves me with the error in my mapserver error log:
[Wed Jan 25 02:28:17 2017].593733 msDrawMap(): Image handling error. Failed to draw layer named 'regional_basin_values'.
[Wed Jan 25 02:28:17 2017].659656 msPostGISLayerWhichShapes(): Query error. Error executing query: ERROR: syntax error at or near "select"
LINE 1: ..._BASIN_TIMESERIES', 1484438400) as subquery where select * &...
^
[Wed Jan 25 02:28:17 2017].659862 msDrawMap(): Image handling error. Failed to draw layer named 'regional_basin_product'.
[Wed Jan 25 02:28:22 2017].836950 msPostGISLayerWhichShapes(): Query error. Error executing query: ERROR: syntax error at or near "select"
LINE 1: ..._BASIN_TIMESERIES', 1484438400) as subquery where select * &...
Finally, I tried leaving the front part of the query within the mapfile and only turning the subquery into the stored procedure:
mapfile:
DATA "geom from (select * from ingest_ffgs_prod_composite_csv('%prod_table%', 1484438400)) as subquery using unique gid using srid=4326"
stored procedure:
RETURN QUERY
EXECUTE 'SELECT g.gid,
g.geom,
g.basin,
a.date,
a.value
FROM sarffg_basins_00_regional_3sec AS g
JOIN '||tablename_ts||' AS a
ON g.basin = a.basin
WHERE a.date = '''||adj_timestamp||''');
And this leaves me with:
[Wed Jan 25 02:35:36 2017].527302 msDrawMap(): Image handling error. Failed to draw layer named 'regional_basin_values'.
[Wed Jan 25 02:35:36 2017].617289 msPostGISLayerWhichShapes(): Query error. Error executing query: ERROR: column "VALUE" does not exist
LINE 1: select "VALUE",encode(ST_AsBinary(ST_Force2D("geom"),'NDR'),...
^
[Wed Jan 25 02:35:36 2017].617511 msDrawMap(): Image handling error. Failed to draw layer named 'regional_basin_product'.
[Wed Jan 25 02:35:42 2017].103566 msPostGISLayerWhichShapes(): Query error. Error executing query: ERROR: column "VALUE" does not exist
LINE 1: select "VALUE",encode(ST_AsBinary(ST_Force2D("geom"),'NDR'),...
The return statement being executed here is:
RETURN QUERY
EXECUTE 'SELECT g.'||quote_ident('gid')||',
g.'||quote_ident('geom')||',
g.'||quote_ident('basin')||',
a.'||quote_ident('DATE')||',
a.'||quote_ident('VALUE')||'
FROM sarffg_basins_00_regional_3sec AS g JOIN '||quote_ident(prod_table)||' AS a
ON g.'||quote_ident('basin')||' = a.'||quote_ident('BASIN')||'
WHERE a.'||quote_ident('DATE')||' = '''||adj_timestamp||'''';
I have verified that prod_table has a column called "VALUE", so I'm not sure why I would be seeing this error. It is also important to note that calling my procedure from within psql yields no errors.
(I have two very similar return statements because my code queries a table with capital column names, and in the absence of that table it creates one from a CSV that doesn't have the capital names.)
Also not sure if it's relevant but here is what my function returns:
RETURNS table (
gid integer,
geom geometry(MultiPolygon,4326),
basin double precision,
date timestamptz,
value double precision
)
Any help would be greatly appreciated
I guess, you use the field VALUE in a filter or something similar in the mapfile (hard to say for sure without mapfile).
This filter must expect capitalized column names and this is why the original query had also capitalized column names:
select g.gid, g.geom, g.basin, a.\"DATE\", a.\"VALUE\" from....
If so, you only have to capitalize the columns returned by your procedure:
RETURNS table (
gid integer,
geom geometry(MultiPolygon,4326),
basin double precision,
"DATE" timestamptz,
"VALUE" double precision
)
Remember that in PostgreSql the case of column and table names matter if you surround then with double quote.
This query:
SELECT VALUE from ...
is case independent, while this one:
SELECT "VALUE" from ...
really requires a table with capitalized column names. And tables with capitalized column names require double quote:
CREATE TABLE test ("VALUE" text, .....

How to perform "a UNION b" when a and b are CTEs?

If I try to UNION (or INTERSECT or EXCEPT) a common table expression I get a syntax error near the UNION. If instead of using the CTE I put the query into the union directly, everything works as expected.
I can work around this but for some more complicated queries using CTEs makes things much more readable. I also just don't like not knowing why something is failing.
As an example, the following query works:
SELECT *
FROM
(
SELECT oid, route_group
FROM runs, gpspoints
WHERE gpspoints.oid = runs.start_point_oid
UNION
SELECT oid, route_group
FROM runs, gpspoints
WHERE gpspoints.oid = runs.end_point_oid
) AS allpoints
;
But this one fails with:
ERROR: syntax error at or near "UNION"
LINE 20: UNION
WITH
startpoints AS
(
SELECT oid, route_group
FROM runs, gpspoints
WHERE gpspoints.oid = runs.start_point_oid
),
endpoints AS
(
SELECT oid, route_group
FROM runs, gpspoints
WHERE gpspoints.oid = runs.end_point_oid
)
SELECT *
FROM
(
startpoints
UNION
endpoints
) AS allpoints
;
The data being UNIONed together is identical but one query fails and the other does not.
I'm running PostgreSQL 9.3 on Windows 7.
The problem is because CTEs are not direct text-substitutions and a UNION b is invalid SELECT syntax. The SELECT keyword is a mandatory part of the parsing and the syntax error is raised before the CTEs are even taken into account.
This is why
SELECT * FROM a
UNION
SELECT * FROM b
works; the syntax is valid, and then the CTEs (represented by a and b) are then used at the table-position (via with_query_name).
At least in SQL Server, I can easily do this - create two CTE's, and do a SELECT from each, combined with a UNION:
WITH FirstNames AS
(
SELECT DISTINCT FirstName FROM Person
), LastNames AS
(
SELECT DISTINCT LastName FROM Person
)
SELECT * FROM FirstNames
UNION
SELECT * FROM LastNames
Not sure if this works in Postgres, too - give it a try!