Copy output of WITH subquery to CSV in postgres - postgresql

I am trying to save the output of below 'WITH' sub-query to a csv file.
WITH mer9 AS (
SELECT *,
substring(seq_window_mut_9mers, split9.start, 9)
FROM split9
),
mer23 AS (
SELECT *,
substring(seq_window_mut_23mers, split23.start, 23)
FROM split23
),
dataset AS (
SELECT *
FROM table
INNER JOIN mer9 ON mer9.seq_window_mut_9mers = table.seq_window_mut_9mers
INNER JOIN mer23 ON mer23.seq_window_mut_23mers = table.seq_window_mut_23mers
)
COPY (SELECT * FROM dataset) TO '/tmp/filename.csv' (format CSV);
After running the query, I am getting an error:
[Code: 0, SQL State: 42601] ERROR: syntax error at or near "COPY"
Position: 3566 [Script position: 3566 - 3570]

Result sets generated from a CTE cannot be accessed in a different query. A CTE creates a sort of "temporary table" that only exists in the current query. That being said, put your CTE inside of the COPY statement and it should work, e.g.
COPY (
WITH mer9 AS (
SELECT *, substring(seq_window_mut_9mers, split9.start, 9)
FROM split9),
mer23 AS (
SELECT *, substring(seq_window_mut_23mers, split23.start, 23)
FROM split23),
dataset AS (
SELECT * FROM table
INNER JOIN mer9 ON mer9.seq_window_mut_9mers = table.seq_window_mut_9mers
INNER JOIN mer23 ON mer23.seq_window_mut_23mers = table.seq_window_mut_23mers
)
) TO '/tmp/filename.csv' (format CSV);
Edit. As pointed out by #a_horse_with_no_name:
Keep in mind that this command will create a file in the server. If you wish to create a file with the output in the client, consider using STDOUT in your COPY command, e.g. using psql:
$ psql -d yourdb -h yourdbhost -U your_user -c "COPY (WITH..) TO STDOUT" > file.csv
See also this answer.

Related

Difference in CTE using SQLite3 and PostgreSQL

I'm practicing SQL in Jupyter Notebook. I use sqlaclhemy and psycopg2 libs for practicing PostgreSQL syntax (using ElephantSQL) and sqlite3 lib for local db.
I have a request:
sql = '''
with medium_credits as (
select t.credit_amount from german_credit t
where t.credit_amount > 1000 and t.credit_amount < 3000
group by t.credit_amount),
medium_credits_info as (
select * from german_credit t
where t.credit_amount in medium_credits)
select t.purpose, t.housing, count(1) as count
from medium_credits_info t
group by t.purpose, t.housing
'''
Running this request using pd.read_sql(sql,connection), where connection is object created with sqlite3 - it goes great.
When I try to try it in Postgres-like system using pd.read_sql(sql,engine), where engine is object created with sqlalchemy, it throws a ProgrammingError:
ProgrammingError: (psycopg2.errors.SyntaxError) syntax error at or near "medium_credits"
LINE 14: where t.credit_amount in medium_credits)
I guess, Postgres doesn't let you use values from CTE-created table directly this way.
Is there any option I could run this code without an error?
PS: local and elephantsql databases are identical
try this :
with medium_credits as (
select t.credit_amount from german_credit t
where t.credit_amount > 1000 and t.credit_amount < 3000
group by t.credit_amount),
medium_credits_info as (
SELECT *
FROM german_credit t
INNER JOIN medium_credits m
ON m.credit_amount = t.credit_amount)

Postgres query syntax error . I am querying in navicat

I try to add quotes. But it did not work:
I'm using Postgres.
Here is my query in navicat which results in syntax errors:
WITH t1 AS
(
SELECT
*
FROM
"olympics_history"
)
Yes it works like this:
WITH t1 AS
(
SELECT
*
FROM
"olympics_history"
)
SELECT games
FROM t1
WHERE t1.season = 'Summer'
Thanks #a_horse_with_no_name

ERROR: Teradata prepare: Syntax error when usign date format 'ddmmyyy'd in SAS

I'm using this code to extract information from this database. However, it is showing me this error:
ERROR: Teradata prepare: Syntax error, expected something like ')' between a string or a Unicode character literal and the word
'd'. SQL statement was: WITH vmher102ult as ( select cod_cte, max(fec_consulta) as max_fec_consulta from
klarmxpw_her.vmher102 where cod_cte not in ('','0','00000000') and fec_consulta>='01MAR2021'd group by cod_cte) select t1.*
from klarmxpw_her.vmher101 as t1 inner join vmher102ult as t2 on t1.cod_cte=t2.cod_cte and
t1.fec_consulta=t2.max_fec_consulta.
The code I'm using for this pass through is the following:
proc sql;
connect to teradata as tera (user=&tuser. password=&tpass. server='TDMX03');
create table vmher101_m as
select * from connection to tera (
WITH vmher102ult as (
select cod_cte, max(fec_consulta) as max_fec_consulta
from klarmxpw_her.vmher102
where cod_cte not in ('','0','00000000')
and fec_consulta>='01MAR2021'd
group by cod_cte)
select t1.*
from klarmxpw_her.vmher101 as t1
inner join vmher102ult as t2
on t1.cod_cte=t2.cod_cte and t1.fec_consulta=t2.max_fec_consulta);
disconnect from ter;
Does anybody know what can I do?
You need to use TERADATA code inside the () after from connection to tera.
Try
and fec_consulta>= DATE '2021-03-01'
Teradata Documentation

How to use a recursive query in a subquery in PostgreSQL

I created a recursive query that returns me a string of the productcategory history (typical parent-child relation:
with recursive productCategoryHierarchy as (
--start with the "anchor" row
select
1 as "level",
pg1.id,
pg1.title,
pg1.parentproductgroup_id
from product_group pg1
where
pg1.id = '17e949b6-85b3-4c87-8f76-ad1e61ea01e1' --parameterize me
union all
-- Get child nodes
select
pch.level +1 as "level",
pg2.id,
pg2.title,
pg2.parentproductgroup_id
from product_group pg2
join productCategoryHierarchy pch on pch.parentproductgroup_id = pg2.id
)
-- Get hierarchy as string
select
CONCAT('',string_agg(productCategoryHierarchy.title, ' > '),'')
from productCategoryHierarchy;
Now I want to use this result in another query as a subquery so that I can use the created string as an attribute in the parent query. Is that possible in Postgres or is there another solution to get a hierarchical tree as string in an attribute?
Are you looking for something like this?
with recursive productcategoryhierarchy as (
...
), aggregated_values as (
select string_agg(productCategoryHierarchy.title, ' > ') as all_titles
from productCategoryHierarchy
)
select ..., (select all_titles from aggregated_values) as all_titles
from ... your main query goes here ..

How to quote column names on the commandline of fbexport

As the title says, how am I going to deal with a column name in FBExport that look like a keyword?
this is how my statement looks like:
-Q "SELECT a.ID, a.USERID, a.`WHEN`, a.INOUT FROM ATTENDANT a"
then I get this error:
Engine Code : 335544569
Engine Message :
Dynamic SQL Error
SQL error code = -104
Token unknown - line 1, column 26
WHEN
When I use
"WHEN"
Error: Switches must begin with -
tried 'When'
-Q "SELECT a.ID, a.USERID, a.'WHEN', a.INOUT FROM ATTENDANT a;"
SQL Message : -104
Invalid token
Engine Code : 335544569
Engine Message :
Dynamic SQL Error
SQL error code = -104
Token unknown - line 1, column 26
'WHEN'
Error: Switches must begin with -
What are the correct escape characters?
For dialect 3 database, Firebird allows quoting object names using double quotes ("<objectname>"). Be aware that quoting object names makes them case sensitive, so "WHEN" is not the same as "when". If your database is dialect 1 then this is not possible, and you should first convert your database to dialect 3.
However the problem this is a command line option, meaning that
-Q "SELECT a.ID, a.USERID, a."WHEN", a.INOUT FROM ATTENDANT a"
Is split by your shell to the arguments:
-Q
SELECT a.ID, a.USERID, a.
WHEN
, a.INOUT FROM ATTENDANT a
While you want:
-Q
SELECT a.ID, a.USERID, a."WHEN", a.INOUT FROM ATTENDANT a
To achieve that, you need to escape the double quote inside the second argument, so:
-Q "SELECT a.ID, a.USERID, a.\"WHEN\", a.INOUT FROM ATTENDANT a"
or - as indicated by a_horse_with_no_name in the comments - wrap the argument in single quotes:
-Q 'SELECT a.ID, a.USERID, a."WHEN", a.INOUT FROM ATTENDANT a'
This doesn't really have to do with Firebird or FBExport, but is a result of how your shell (eg bash) parses commandline arguments.
It looks like someone else is dealing with the external access to the Firebird database from Safescan TimeAttenedant
It was a little bit stupid from Safescan to name a column WHEN because this is a keyword in Firebird.
In the context of an insert statement, I have no success with a column list like:
insert into attendant (ID, USERID, DEVICEID, WHEN, INOUT, VERIFYMODE, WORKCODE) values (1092, 1, 1, '28.08.2017 08:00', 0, 4, 3);
"WHEN", \"WHEN\", \'WHEN\', ... no success
Remedy - Insert all data without column list, ex:
insert into attendant values (1034, 2, 1, '28.08.2017 08:00', 0, 4, null, null, null, null, null, 3);
Query is much easier: select * from attendant;